OVERALL HOME    Other material for programmers, not Arduino specific
ARDUINO: Top Page    Branch "A": Arduino Course    Branch "B": Arduino "How To"s and Projects
ArduServer and AdruSimpSrv: HOME
-d- Bookmark this on Delicious   Recommend to StumbleUpon

Teensy (Arduino cousin) as web server with a Wiz820io: ArduServe3

The Sourcecode

Input and output locally or across the internet

This page is browser friendly, by the way. Make your browser's window less wide than your whole screen and you will find the narrower columns much easier to read. For more tips, see my Power Browsing hints.

This page is not(?) enough

I strongly recommend that you at least skim through the information on my page about how the ArduServer2 code was developed, but if you want just "the answer", here it is. At least here is the Teensy half of things. You use an ordinary web browser, e.g. Firefox, for the client. You can access an ArduServer over your LAN or across the internet.

I developed the following in November 2014, on a Windows 7 machine, with the Arduino environment 1.0.6, and Teenyduino (Teensy Loader) 1.20


ArduServe with Wiz820io....

You will have to change one line if you don't want to use port 80.

You will have to change the several lines with my URL (http://mon7nc...) if you want access across the internet. (Change the URL from my URL to your URL.)

You'll need to alter the LAN address line, if you haven't put your ArduServer on 192.168.0.240.

You may to change the line which sets the device's MAC. (You can use any number that isn't already used by something else on your LAN.)

If your LED is not on D5, and your phototransistor on A1, there will be other simple, single-line changes to make.

Software to monitor ArduServer2

I have a Windows program which can run in an internet connected computer anywhere in the world, and keep an eye on the temperature where an ArduServer2 is. If the temperature falls below a level of your choosing, an alarm goes off.... the PC begins beeping. This is up and running, but not yet in a version for selling. If you want me to get the commercial version launched, write and say so, I'll see if I can get to it! Somehting similar could be written for ArduServer3

Arduserver 3 support circuits:

-

The Teensy Sourcecode....

/* "ArduServer3" by TK Boyd
version? See "ver" constant
Help? See http://Arduserver.com */

//There is a LOT of Bad Code in this... but only in respect of
//  FWWBuf and related matters. Not really relevant to what I
//  imagine brought you here: A demo of the basis for Home Automation,
//  remote sensing, etc. with Arudino/Teensy over the internet.
//(Code will work in Teensy EXACTLY like this, and not much changed
//  in an Arduino.

//MOVE TAKE TTURE READINGS UP, deal with putting READING, not marker "5.21" in FWW line
//For farwatchwathcer

/* This code this derives from is HEAVILY based on the example
"WebServer" supplied with (at least) the Arduino environment 0022,
August 2011. Arduserver3 was an evolution of Arduserver2, which is
where the "WebServer" example was first used as a basis.

Arduserver3 was developed Nov 14 with...
Arduino software 1.0.6
Windows 7
A Teensy 3.1, with a Wiznet820io module.

You DON'T, in the environment described above, need the
w5100.cpp, w5100.h library files you may come across
if you search the web.

--------------
Arduserver3: A complete statement of What's Needed...
(at least I will TRY to make it complete)

Hardware & software envirinment: See above, plus...

Incorporated in this code:
   include <SPI.h>, <Ethernet.h>: Using "just" the standard
      library modules supplied with the 1.0.6 Arduino
      environment.... but be aware: They MAY be altered during
      the installation of Teensyduino. Which may be good for
      the Teensy's needs, and either benign or helpful for
      "real" Arduinos. I hope so, anyway! (The two includes
      were part of Arduserver2, too, but I want to be clear
      about What You Need.

Pins used....
   By Wiz820io, as married to Teensy by shield from www.pjrc.com/
   (Table copied from their site. The SD card is not used in
   Arduserver3, but its pins might just as well be avioded.
   The MCP1825 is a voltage regulator on the shield.

 Teensy3   SD Card   WIZ820io      MCP1825     JUMPER PADS
 -------   -------   --------      -------     -----------
   4        2:CS
   8                                             Left Side
   9                  RESET
  10:CS               SS
  11:DOUT   3:DI      MOSI
  12:DIN    7:DO      MISO
  13:SCK    5:CLK     SCLK
  VIN                               1:IN
            4:VDD     VIN33,VIN33   3:OUT
  GND       6:VSS     GND,GND,GND   2:GND+TAB   Right Side
                      PWDN                      Center

ALSO from the pjrc.com site...

"Some SD cards can be sensitive to SPI activity while
  the Ethernet library is initilized before the SD library.

"For best compatiblity with all SD cards, these 3 lines
  are recommended at the beginning of setup().
  Pins 4 and 10 will be reconfigured as outputs by
  the SD and Ethernet libraries. Making them input
  pullup mode before initialization guarantees neither
  device can respond to unintentional signals while
  the other is initialized."

((Following HAS BEEN added to Arduserver3)))
void setup() {
  pinMode(4, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  delay(1);  // allow time for both pins to reach 3.3V

(End "also from pjrc.com site")

Other pins used are as follows. The following means that
the LED (which users of the server can turn on and off)
should be on pin 7, etc. These assignments can be changed,
if you'd rather things were elsewhere.... just don't change
them TO a pin already in used by the Wiz820io (+SD card) shield


const byte bLEDpin=6;//The LED users of the web page can turn on and off
const byte bBeeperPin=7;//A local "beeper" (self oscillating) to tell those
   near the server that it has been accessed
const byte bTturePin=5;//Pin used to connect a Dallas DS18B20 tture
   sensor. This is optional, not "core" to what Arduserver does.)
const byte bAnInWatchLEDPin=0;//For photosensor that monitors the LED
   the user can turn on and off. Reading on this confirms for remote
   users that their actions had the desired effect
const byte bAnInWatchAmbientLightPin=0;//Not core to what Arduserver does.

=== Old documetation....
From the example "WebServer" supplied
with (at least) the Arduino environment 0022,
August 2011.... BEGIN (edited) QUOTE...

A simple web server that shows the value of the analog input pins.
 using... in Arduserve2 an Arduino W5100 Ethernet shield,
 in Arduserver3 a Wiznet820io

 Circuit: (ARDUSERVER2!... see other for Arduserver3)
 * Ethernet shield attached to pins 10, 11, 12, 13
 * Analog inputs attached to pins A0 through A5 (optional)

 ADDED TO DEMO by TKB:

 N.B.: May need changing from instance to instance...

 IP addresses... LAN and internet URL (latter appears several places)
 Port
 Pin assignments

 ... added to demo continued...
 A light sensor on (A0) looking at room's ambient light... not
      central to function of demo, but needed, if text on served web
      page to be valid
 A light sensor on (A1), which an LED shines on when it is shining.
      Probably best to wrap them together with opaque tape, sort
      of a poor man's "opto-isolator"
 An LED + resistor on pin designated by value in bLEDpin
 A beeper on pin designated by bBeeperPin... not essential to demo
(Bring pin high to turn either on... "beeper" makes continual
    whine while on.)
Also added a Dallas 1-Wire temperature sensing chip, DS18B20, on input 5.
    The internal ID of YOUR temperature sensing chip will need entering
    into the program if you want to use the same facility, and the
    1-Wire reading code in this is VERY crude.. you may want to replace
    it. It will only read a DS18B20, for instance.
    ** N.B. ** The signal line needs to be pulled up to 5v. through a
    4k7 reisitor when working with the Teensy, a 3v3 device internally,
    with 5v tolerant inputs. I was using my DS18B20 *not* "parasitically
    powered", i.e. one pin to 5v, one pin to ground, the last pin Dallas
    data pin. See http://sheepdogguides.com/dst9parasitic.htm for
    more on the "parasitic power or not?" question, if you want it.

(End "ADDED"... quote continues...)

 created 18 Dec 2009
 by David A. Mellis
 modified 4 Sep 2010
 by Tom Igoe

... END QUOTE... and please remember, Mellis & Igoe's
code has been MESSED WITH.
Things that work: All credit to them.
Things that don't: Probably because TKB "broke" them!

Aspects of this are still a DOG'S DINNER... but it works!....
*/

#include <SPI.h>
#include <Ethernet.h>
//#include <OneWire.h> will have to convert code if this used.
//13 Nov 14: Was having no joy with old code, remmed out the report
//Chip fried?

const char ver[]="14 Nov 2014";//Plus Wiznet to W5100
/*THE LETTER AT THE END OF THE DATE shows not,
which would be usual in my work, a later version
of something done earlier on the same day.

Instead, there are four versions of ArduServer2...
"a", "b", "c" and "d", identified by the last letter
of the version ID.

Version "21 Jan 12d" was best and (at this point) latest version
of ArduServer2 when development stalled. Was "finished".

Old-at-11/14 note:
KEEP THE VERSION ID TO 10 characters:
  The page served is nearly "too full", and
  the "ver" string is inserted into the HTML.


HISTORY:

Changes from Arduserver2, ver "21 Jan 12d" to create
  Arduserver3. (I will TRY to keep this comprehensive!)

Arduserver3 was built from Arduserver2, taking ver
"21 Jan 12d" of Arduserver2 from http://arduserver.com/a5as2code.htm
on 13 Nov 14.

There are "messy bits" left over from earlier editions, but the idea
was to "prove" that the Teensy + WIZ820io were practically
"drop in replacements" for previous hardware.

In Arduserver, Arduserver2, and Arduserver3, you may well have
  to make changes to the constants set up for ip[], mac[] and bPort
  (These are similar to setting a static IP address for any device
  you may want to put on your LAN.)

Where Arduserver2, and the OLD "official" server example had...
  Server server(bPort); ... in the 1.0.6 "Server" example,
  and for Arduserver3, we want...
  EthernetServer server(bPort);

  Similarly...
     Client client = server.available
     became
     EthernetClient client = server.available

Some changes were made which are not documented here, such as
changing the title of the page from "Arduserver 2" to
"Arduserver 3". These were just details of my use of what
the Teensy+Wiz820io made possible, and I thought them too
distracting.

I WILL mention re-enabling all the code relating to the
Revolver Map. In my previous Arduserver, that had to be
sacrificed as I could not, in the previous environment,
have such a large page.

Reading of 1-wire chip heavily re-written

*/

//Constants which determine what the Arduserver calls dark/dim/well lit
const int iLightLevelDark=4;//Below or equal to this: "Dark"
const int iLightLevelDim=15;//Above (or equal?) this: "Well lit"
//Between them: "Dimly lit"


const byte bLEDpin=6;
const byte bBeeperPin=7;
const byte bTturePin=5;
const byte bAnInWatchLEDPin=0;
const byte bAnInWatchAmbientLightPin=1;
const byte MaxArrayElement=252;
/*Defines the size of the array for holding the first
  characters in each line coming in with the http requests
  FOR SOME REASON, setting it to about 25 caused bad problems...
  I can't see why this happens. To be investigated!*/

/**********
YOU MAY HAVE TO CHANGE THE NUMBERS HERE.......

Set up a port number, MAC address and IP address for your
controller below.

Port 80 is usual for HTTP. (I needed 81 for
    special circumstances: two servers on one IP address)
The MAC address will need changing if you have two devices on
    your LAN with the same MAC address.
The IP address may need changing, depending on your LAN, and
    what is on it already. There must not be two devices with
    the same IP address on the same LAN.

While you would not want to change what is in mac[] or ip[]
    while the program is running, you cannot make them constants,
    or the call of Ethernet.begin(mac, ip); will not compile. */

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192,168,0,240};//240 7NC... shared with old, nuElec, 254 SX
const byte bPort = 81;

/* Initialize the Ethernet server library. At the
  same time, tell it the port you want to use.*/
EthernetServer server(bPort);

/* Aborted start of re-write of 1-wire code from example
OneWire ds(bTturePin);
byte addr[8];//fpr OneWire
byte data[12];//for OneWire
float celsius;//for OneWire
*/


char c,cMstRecentCmnd='/';
/*That '/' is part of one of the crude aspects of the current code.
  If someone accesses the page without giving a command, the "command"
  the software sees is '/'... so '/' is being used as an unreliable
  rogue saying "no command given". However, if an invalid command is
  given, anything can be harvested as "the command". AND, if the user
  used...
     (URL)/?cmd=/
  ... then a "valid" '/' would arrive as "the command, but be ignored,
  as it would be though to be representing "no valic command".

  As I said... the server works, but it isn't very robust. It only
  accepts two commands, and they have to be presented properly.

  They are, and are presented, thus...

       /?cmd=0
       /?cmd=1
*/

char cLineBuffer[MaxArrayElement];
byte bPlaceInBuffer;
word wClicksProcessed=0;
//Next is a global which will be "messed with" in various
//  places before being used as an element in the text
//  output by Arduserver3. It is ONLY improtant if you are
//  interested in monitoring Arduserver3 with FarWatchWathcer.
char FWWBuff[18]="1234S220055556666";//x bytes for chars, plus 1 for null

//The following is NOT important to the basic TCP/IP
//  elements of this program. It is merely something
//  to make facilitate the temperature sensing/reporting
//My thanks to the authors of http://playground.arduino.cc/Code/Struct
//  for helping me see how to use "Struct"
struct StructTture {
  char cSign;//Will hold '+' or '-'
  word wCombined;//Will hold 351 if tture was + OR - 3.51 deg Celcius
  byte bWhole;//Will hold 3, if tture was + or - 3.51
  byte bFrac;//Will hold 51 if tture was + or - 3.51
};

StructTture Tture;//Set up a global structure for managing Tture readings

void ReadTtureSensor()
//In a perfect world, the function would return
//  a value of type StructTture... but that isn't
//  available in Arduino (by any easy means), so
//  we will fill the elements of a global StructTture-type
//  variable, and thus still have SOME of the benefits
//  of Structured datatypes.
//The subroutine fills these, as follows, if sensir reads +3.51 deg C
//     Tture.cSign='+';
//     Tture.wCombined=351;
//     Tture.bWhole=3;
//     Tture.bFrac=51;
{
  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;

  OneWireReset(bTturePin);
  OneWireOutByte(bTturePin, 0xcc);
  OneWireOutByte(bTturePin, 0x44); // perform temperature conversion, strong pullup for one sec

  OneWireReset(bTturePin);
  OneWireOutByte(bTturePin, 0xcc);
  OneWireOutByte(bTturePin, 0xbe);

  LowByte = OneWireInByte(bTturePin);
  HighByte = OneWireInByte(bTturePin);
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  Tture.cSign='+';//provionally!
  if (SignBit) // negative
  {
    Tture.cSign='-';
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Tture.bWhole=Whole;//This and prev: Combine, write out Whole?

  Fract = Tc_100 % 100;//This and next: Combine, write out Fract?
  Tture.bFrac=Fract;

  Tture.wCombined=(Tture.bWhole*100)+Tture.bFrac;
  delay(1200);      // Delay.  For DS1820 at full precision, at least 1000 needed
};//end of ReadTtureSensor()

void PutCharInFWWBuff(byte bWhere, char cTmp)
//A function to change characters in the string FWWBuff, a global variable.
//N.B.: Spec bWhere as 0 to replace FIRST char in string.
//Problems will arise.. big problems... if "bad" bWhere passed to routine
{
FWWBuff[bWhere]=cTmp;
};

char CharFrmNum(int iTmp, int bWhich)
//(There must be a better way... this only needed
//   if you want the FWW lines.
// Part of turning a number to a string of char)
//For iTmp=1234 and bWhich=3, will return '2'
//Fails if iTmp negative or >9999
// "/" is "DIV" operator.... 456 DIV 100 is 4
//Does leading zeros without extra hassle anywhere...
// (0 is returned for CharFrmNum(999,4))
{
 int iTmp2,bTmp1,bTmp2;
 char Digits[11]="0123456789";//Yes.. this should go elsewhere,
 //  no need to "do" over and over.
 if (bWhich==1){bTmp1=1;bTmp2=10;};
 if (bWhich==2){bTmp1=10;bTmp2=100;};
 if (bWhich==3){bTmp1=100;bTmp2=1000;};
 if (bWhich==4){bTmp1=1000;bTmp2=10000;};
 iTmp2=((iTmp % bTmp2)-(iTmp % bTmp1))/bTmp1;
 return Digits[iTmp2];
};

void Stuff4InFWWBuff(byte bWhere,int iTmp)
//It should be possible to do this BETTER... but I cheated
//  to Get It Done.
//Converts iTmp to 4 characters, moves them to a place in
//  the global variable FWWBuff
//Spec bWhere as 0 to put the 1st of the characters in the
//  first character of FWWBuff
//Routine will be in trouble if iTmp >9999 or <0
//Problems will arise.. big problems... if "bad" bWhere passed to routine
{
char sTmp[5];//Create array to hold 4 chars+terminating null.
if (iTmp<1000) {sTmp[0]='0';} else {sTmp[0]=CharFrmNum(iTmp,4);};
if (iTmp<100) {sTmp[1]='0';} else {sTmp[1]=CharFrmNum(iTmp,3);};
if (iTmp<10) {sTmp[2]='0';} else {sTmp[2]=CharFrmNum(iTmp,2);};
if (iTmp<1) {sTmp[3]='0';} else {sTmp[3]=CharFrmNum(iTmp,1);};

PutCharInFWWBuff(bWhere,sTmp[0]);
PutCharInFWWBuff(bWhere+1,sTmp[1]);
PutCharInFWWBuff(bWhere+2,sTmp[2]);
PutCharInFWWBuff(bWhere+3,sTmp[3]);
};

void setup()
{
  //A few things to make pjrc.com shield's SD card (if used in
  //  extension of Arduserver3... irrelevant to IT) behave...
  pinMode(4, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  delay(1);  // allow time for both pins to reach 3.3V

// start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();

  //Serial.begin(9600);//Restore, if you want to monitor program's
       //operation via serial monitor

  pinMode(bBeeperPin,OUTPUT);
  digitalWrite(bBeeperPin,LOW);

  pinMode(bLEDpin,OUTPUT);
  LEDOff();

//For tture sensing... (2 lines
    digitalWrite(bTturePin, LOW);
    pinMode(bTturePin, INPUT);
}

void loop()
{ int iAn0,iAn1;//Type word might have been better. NOTE: "An0" does not
//necessarily reflect a reading from the device's analog CHANNEL 0.
//Gather readings, before starting the TCP/IP stuff...
  iAn0=analogRead(bAnInWatchAmbientLightPin);//We will use iAn0 TWICE, later.
  iAn1=analogRead(bAnInWatchLEDPin);//We will use iAn0 TWICE, later.
  ReadTtureSensor();//Fills the fields of the global "Tture"

  EthernetClient client = server.available();//1.... these rems, with numbers, remnants from
       //development of the program, retained in case they help describe the
       //final version. Which lines have them is a quirk of fate.
  if (client) {//2
    boolean currentLineIsBlank = true;//3
    bPlaceInBuffer=0;
    char cCmnd='H';//Rogue for "no command"
       //In current CRUDE scheme, after URL, either nothing
       //... in which case an 'H' is seen (H of HTTP is picked up)
       //or a question mark (to be traditional) followed by
       //   /?cmd=
       //followed by one case sensitive, program hardcoded character.
       //See subroutine DoCmnd for what the commands are, what they do.

    cMstRecentCmnd='H';//Init with rogue

    while (client.connected()) {//4
      if (client.available()) {//5
         c = client.read();//6
         if ((c!='\n') && (c!='\r')){
           cLineBuffer[bPlaceInBuffer]=c;
           if (bPlaceInBuffer<MaxArrayElement) {bPlaceInBuffer++;};
           }
         //Serial.print(c);
         if (c == '\n' && currentLineIsBlank) {//7
            delay(250);//Give light sensor a moment to register changed light level...
               //LDR response sluggish.. but even phototransistor needs a little time
               //During "DoCmnd" an LED may have been turned on or off/
               //Can be much shorter with better sensor.

            wClicksProcessed++;//A frill
            ShortBeep();//A frill

            //Current code (ver 6 Sept 11c: 2 sensors, 2 buttons, RevolverMap)
            //VERY CLOSE to too much code.... add more, and watch closely for
            //bad and poorly reported misbehaviour.

            client.println("HTTP/1.1 200 OK");//8
            client.println("Content-Type: text/html");//9
            client.println();//10

            /*The HTML created by this program is far from
              "well crafted". But it does the job... */

            client.println("<html>");
            client.println("<head>");
            client.print("<title>ArduServ3</title>");
            client.println("</head>");
            client.println("</head>");
            client.println();
            client.println("<body>");

   //Now we will insert four "comment" lines in the page of
            //  HTML to be served up.
            //They are for the use of FarWatchWatcher (FWW), a Windows app which
            //  checks web servers periodically, watching for "bad" conditions,
            //  and raising an alarm, if bad conditions seen. There is a webpage
            //  about FarWatchWatcher, cited in the first line...
            //There is a further comment at the end of this block of code.
            //If you are not interested in FarWatchWatcher, you can ignore this
            //  block, it merely, as I said, adds three lines of comments to
            //  the page served up.
            client.println("<!--NeXtLiNe4FWWdf001. (http://sheepdogsoftware.co.uk/ssdd67.htm)-->");
            //"NeXtLiNe4FWW is a rogue, a "fingerprint", for finding by FarWatchWathcer
            //   the df001 indicates that the data line (which comes next) will use
            //   a particular data syntax: 4 fields, 4/5/4/4 characters each.
            //Record format: ccccSttddxxxxyyyy
            //As part of the df001 definition, we further promise that only
            //   the fifth character will be anything but a digit. (5th char: + or -
            //   first field: count of "clicks seen", or some other "count"
            //      which should change endlessly, to help FWW detect a
            //      stalled server which is producing a page, but a static page.
            //   second field: tture in Celcius:sign, 2 digits integer part,
            //      2 digits fraction. So, -5.3 degrees: "-0530"
            //   third field: four digits. In the case of Aruduserver3, the
            //      reading from one of the analog channels
            //   fourth field: four digits. In the case of Aruduserver3, the
            //      reading from the other monitored analog channel.


            client.print("<!--");
            //Fill FWWBuff with string to be added to page in a moment...
            //Overwrite the first 4 chars of FWWBuff with the
            //digits of the click count...
            Stuff4InFWWBuff(0,wClicksProcessed);

            //Put the sign character in...
            PutCharInFWWBuff(4,Tture.cSign);

            //Four chars for tture (ww/dd, so for 3.5 deg: 0350)
            Stuff4InFWWBuff(5,Tture.wCombined);

            //Four chars for reading from first analog input
            Stuff4InFWWBuff(9,iAn0);

            //Four chars for reading from other analog input
            Stuff4InFWWBuff(13,iAn1);

            //And now, at last.........
            client.print(FWWBuff);
            //... and finish off the comment the FWW "message" goes on.
            client.println("-->");

            client.print("<!--In line before this: 'NeXtLiNe4FWW' rogue/token,");
            client.println("'df001' suggests 'type 001' Data Format, rest is free text.-->");
            client.print("<!--Under df001: ccccSTTttxxxxyyyy: click count; ");
            client.println("Tture sign,whole,frac; analog reading; another.-->mi");
            //End of block of code inserting four comment lines
                 //for FarWatchWatcher

            client.println("<center>");
            client.print("<h2>ArduServer 3, ver ");
            client.print(ver);
            client.println("</h2>");

            client.print("<h3>See <a href=\"http://ArduServer.com\"<"
                "target=\"_blank\">ArduServer.com</a></h3>");
            client.print("<h3>Hardware: Teensy 3.1 / Wiz820io Ethernet Module</h3>");

            client.println("</center>");
            client.println();

            if ((cMstRecentCmnd=='0')||(cMstRecentCmnd=='1')){
                client.print("<p>Cmd received: <b>");
                client.print(cMstRecentCmnd);
                client.println("</b></p>");
                }//no ;
              else {
                client.print("<p>Cmnds: \?cmd=0 and \?cmd=1<br>");
                client.print("Add \"/?cmd=1\" to page URL for different "
                  "text here.</p>");
                };

            client.println("<p>- -");

            client.print("<br>Temperature, degrees C: <b>");

//Here begins small block to insert tture reading, taken earlier
  if (Tture.cSign=='-') // If its negative
  {
     client.print("-");
  }

  client.print(Tture.bWhole);
  client.print(".");

  if (Tture.bFrac < 10)
  {
     client.print("0");
  }

  client.print(Tture.bFrac);
      client.print("\n");

//Here ends block inserting tture reading)

  client.println("</b>");

  client.println("<p>- -");

  client.print("<br>Analog input ");
  client.print(bAnInWatchAmbientLightPin);
  client.print(" reads: <b>");
  client.print(iAn0);
  client.println("</b>");

  client.print("<br>Connected to a "
      "<a href=\"http://www.arunet.co.uk/tkboyd/ec/ec1senslight.htm\" "
      "target=\"_blank\">"
      "phototransistor</a>.</p>");//12

  if (iAn0<=iLightLevelDark)
       {client.println("<p>Room is <b>dark.</b></p>");}
     else
       {if (iAn0<=iLightLevelDim)
              {client.println("<p>Room is <b>dimly lit</b>.</p>");}
            else
              {client.println("<p>Room is <b>well lit</b>.</p>");
              };
        };

  client.println("<p>- -");//12

  client.print("<br>Analog input ");
  client.print(bAnInWatchLEDPin);
  client.print(", senses LED, reads: <b>");//12
  client.print(iAn1);//13
  client.println("</b>");

  /* Here's a crude, but more clear, alternative to the buttons... just use links...
    client.println("</p><p>Click here to turn LED on <a href=\"http://mon7nc.dyndns.org:81/?cmd=0\">"
    "http://mon7nc.dyndns.org:81/?cmd=0</a><br>");
    client.println("Click here to turn LED off <a href=\"http://mon7nc.dyndns.org:81/?cmd=1\">"
    "http://mon7nc.dyndns.org:81/?cmd=1</a></p>");
    */


  /*The following is just(?) a "prettier" way to achieve what the
      links above achieve. You can probably do more with forms than
      you can do with mere links... but we're not going far with the
      modest form code below....   */

      client.println();
      client.println("<form METHOD=get action=\"http://mon7nc.dyndns.org:81/\">");
      client.println("<input type=hidden name=\"cmd\" value=\"1\">");
      client.println("<input type=submit value=\"LED On\">");
      client.println("</form>");
      client.println();

      client.println("<form METHOD=get action=\"http://mon7nc.dyndns.org:81/\">");
      client.println("<input type=hidden name=\"cmd\" value=\"0\">");
      client.println("<input type=submit value=\"LED Off\">");
      client.println("</form>");
      client.println();

/*    client.println("<p>Light sensor watching LED, a mere LDR, responds "
          "slowly... click 'on' (or 'off') several times to "
          "get \"final answer\".</p>");
*/

       client.print("<p>Clicks since server booted: ");
       client.print(wClicksProcessed);
       client.println("</p>");

       client.println("<br>");

       //TKB: New RevolverMap for ArduServer2... mon277..:81...
       //Done 3 Aug 11, 22:25, my third... just after hearing from Kate (on NOLS course) of Xelda's death...
       //First hooked up Uno and "official" Ethernet Shield earlier same evening.

       client.println("<center>");

       /*PLEASE NOTE: This code specific for my page. You need to go to RevolverMaps and get
            your own free code, if you want a similar thing on your own page. Easy!*/

          client.print("<script type=\"text/javascript\" src=\"http://jf.revolvermaps.com/r.js\">");
          client.print("</script><script type=\"text/javascript\">rm_f1st('2','260','true','false','000000','5sgqledqgna',");
          client.print("'true','00ff6c');</script><noscript><applet codebase=\"http://rf.revolvermaps.com/j ");
          client.print("code=\"core.RE\" width=\"260\" height=\"260\" archive=\"g.jar\"><param name=\"cabbase\" ");
          client.print("value=\"g.cab\" /><param name=\"r\" value=\"true\" /><param name=\"n\" value=\"false\" /");
          client.print("><param name=\"i\" value=\"5sgqledqgna\" /><param name=\"m\" value=\"2\" />");
          client.print("<param name=\"s\" value=\"260\" /><param name=\"c\" value=\"00ff6c\" /><param name=\"v\" ");
          client.print("value=\"true\" /><param name=\"b\" value=\"000000\" /><param name=\"rfc\" value=\"true\" />");
          client.println("</applet></noscript>");

      client.println("</center>");

      client.println("</body>");
      client.println("</html>");

      break;//15
      }
      if (c == '\n') {//17
        currentLineIsBlank = true;//18

          //display with buffer contents;
          if (bPlaceInBuffer>0){
             for (byte c1=0; c1<bPlaceInBuffer; c1++){
             //Serial.print(cLineBuffer[c1]);
             }
         //Serial.println();
         if ((cLineBuffer[0]=='G')&&(cLineBuffer[1]=='E')&&(cLineBuffer[2]=='T'))
         /*VERY CRUDE: Always just picks up 11th char of GET line... either the H of...
           GET / HTTP...  or the character after the tradtional "?cmd=", as in...
           GET /?cmd=1 HTTP...  */

           {
             cCmnd=cLineBuffer[10];//Yes: INDEX 10 for 11th character.
             //Serial.print("Command was: ");
             //Serial.println(cCmnd);
             if (cCmnd!='/') {DoCmnd(cCmnd);};
             /*Don't do if cCmnd=='/'... that suggests there
               was no command, or a "?cmd=/" command, which
               should not be added to the range of valid commands
               if the code is revised.*/
           }
         }
         //end "deal with buffer contents"

         bPlaceInBuffer=0;//set back to 0 for next line

        } //19... things like the "19" are remnants of an earlier line ID
              // system
        else if (c != '\r') {        //20
          currentLineIsBlank = false;//21
        }//22
      }//23
    }//24
    delay(1);//25
    client.stop();//26
  }//27
}//28

void DoCmnd(char cLCmnd)
{
if (cLCmnd=='0'){
    //Serial.println("Cmnd was a zero!");
    cMstRecentCmnd=cLCmnd;
    LEDOff();
    };
if (cLCmnd=='1'){
    //Serial.println("Cmnd was a one!");
    cMstRecentCmnd=cLCmnd;
    LEDOn();
    };
}

void LEDOn(){
digitalWrite(bLEDpin,HIGH);
}

void LEDOff(){
digitalWrite(bLEDpin,LOW);
}

void ShortBeep(){
digitalWrite(bBeeperPin,HIGH);
delay(80);
digitalWrite(bBeeperPin,LOW);
}

//New in ver 1 jan 12d from here to "end new..."
//  This is not only new stuff.

void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
     digitalWrite(Pin, LOW);
     pinMode(Pin, OUTPUT); // bring low for 500 us
     delayMicroseconds(500);
     pinMode(Pin, INPUT);
     delayMicroseconds(500);
}//end of OneWireReset

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
   byte n;

   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1)  // test least sig bit
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(5);
         pinMode(Pin, INPUT);
         delayMicroseconds(60);
      }
      else
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(60);
         pinMode(Pin, INPUT);
      }
      d=d>>1; // now the next bit is in the least sig bit position.
    }
}//end of OneWireOutByte

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
    byte d, n, b;

    for (n=0; n<8; n++)
    {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(5);
        b = digitalRead(Pin);
        delayMicroseconds(50);
        d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
    }
    return(d);
}//end OneWireInByte

//end block of new in ver 1 jan 12d stuff
//END OF IT ALL!



I hope that was useful...

Remember: The code is explained for you at my page explaining the ArduServer2's creation.

And there's a separate page with help on the support hardware, including a PCB design for a suitable shield.)




Search for other things...


Please note that I have two other sites, and that the following search will not include them. They have their own search buttons.

My Sheepdog Guides site.
My Arunet site.

   Search this site or the web        powered by FreeFind
 
  Site search Web search
Site Map    What's New    Search
The search engine merely looks for the words you type, so....
*    Spell them properly.
*    Don't bother with "How do I get rich?" That will merely return pages with "how", "do", "I"....

You can also search this site without using forms.
Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows PC) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!
Click here to visit editor's freeware, shareware page.


Want a site hosted, or email? You can also help me if you sign up via this link to 1&1's services. (I wouldn't recommend them unless I was happy after several years as one of their customers, but yes, they do pay me if you use this link! As do the Google advertisers, about whom I know nothing, of course.)



Valid HTML 4.01 Transitional Page tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org

CSS behind the page checked, at least once upon a time!, with http://jigsaw.w3.org/css-validator/
Why does this page cause a script to run? Because of the Google panels, and the code for the search button. Also, I have some of my pages' traffic monitored for me by eXTReMe tracker. They offer a free tracker. If you want to try one, check out their site. Why do I mention the script? Be sure you know all you need to about spyware.


Editor's Main Homepage
How to email or write this page's editor, Tom Boyd

....... P a g e . . . E n d s .....