IANJOHNSTON.COM

...........This Time Next Year...........

  • Full Screen
  • Wide Screen
  • Narrow Screen
  • Increase font size
  • Default font size
  • Decrease font size

Arduino - Home Testing

E-mail Print PDF

ARDUINO TESTING

In preparation to getting stuck into a project or two using the Arduino Platform I decided to start with some testing.
First thing was to get the hardware up & running and write my first program. As follows,

Hardware:
Arduino Duemilanove (Updated 328 Version)
2*16 LCD (running in 4bit mode)

Development Software:
It's called "Arduino IDE" and is used for developing the code and uploading to the Arduino, but yuk, it sucks!, so I looked around for a new text editor, and after playing with WinAVR and MS Visual Studio I have settled on Notepad++ (see here). MUCH better and supports C++ nicely (syntax highlighting etc etc).

I tried out the Arduino Ethernet Shield module, and it works! I managed to setup a wee webserver.
If it's online you can access here - http://www.ianjohnston.com:1234
This program is a work-in-progress, so check back to see it evolve.
Please note that i'm now using a 4*20 LCD (rather than the 2*16 in the pics)

Here's my code below.

Recent mods:
23/01/10 - I needed to set up a timer interrupt to service the LCD (rather than having it update full speed of the cpu which is just a waste of resource), and so rather than code them manually (ugghh!) I found a library component "TimedAction.h"......I highly recommend it!

25/01/10 - Have made quite a few tweaks, trying to optimize the code a bit more. One thing I had made the mistake of was trying to run multiple interrupt routines at the same time, and whilst it worked it must have been causing havoc to the cpu.....I did get the odd Arduino crash. So now I have 1off 250mS interrupt service and any other timing is done from there.
I have also added a neat wee averaging routine "Yn=Yn-1+(1/k*(Xn-Yn-1))" which is great for averaging a raw analogue input as it also integrates the signal such that any spikes in the signal are almost ignored and thus smoothed out.
Finally for today I added a better Uptime Counter and optimized it for the local LCD.

26/01/10 - Experienced problems with corrupt data to the web-browser. Everything pointed towards low memory (32 bytes free!) but after fixing that the problem still exists. I figured the problem lay with the TCP/IP library ethernet.h and after a Google session I hit on this which seems to have fixed the problem, albeit I still seem to have a low memory problem where by the Arduino doesn't start up if I add much more code to the Sendpage print to web browser routine.

27/01/10 - Re-wrote the interrupt timer. Now the main Main Loop is short, the 100mS Timed Loop (interrupt) is very short and almost everything else is in subroutines. The memory problem still exists, however, I have ordered an Arduino Mega so we'll see if that cures it.

28/01/10 - Added in some code to test servo (RC Futaba S3101) driving via PWM. Works a treat.

29/01/10 - Found that the servo was glitching, and realized that this is caused by the servo.h library's own interrupt service is conflicting with my own 100mS service.......so one has to go. I have ditched servo.h and written my own timing routine. Looks a bit more crude on paper than a nice library, but it works far better.

31/01/10 - Moved some stuff from the main loop to the 40mS interrupt loop and got a 10 fold increase in main loop speed. Now down to 0.07mS (70uS).

02/02/10 - Fixed bug in Uptime routine. Still chasing fact that there seems to be a limit to how much I can sent to web client.

06/02/10 - Added remote digital I/O via I2C bus.

09/02/10 - Replaced LCD with I2C interface LCD, thus freeing up I/O.

Video demo:-

Pic:-

Here's the current code:

/***********************************************************************************************
* IANJ'S ARDUINO WEB SERVER / LCD / RC SERVO DRIVE PWM / ETHERNET
* Ian Johnston Jan 2010
* Requires an Ethernet Shield & Arduino.
* (http Parsing routines courtesy of original code by Alessandro Calzavara & Alberto Capponi)
*
* Running on an Arduino Duemilanove
*
************************************************************************************************/

#include <Ethernet.h>
#include <EEPROM.h>
#include <avr/pgmspace.h>
#include <TimedAction.h>
#include <Wire.h>
#include <ByVacLCD.h>

// Setup LCD (http://www.byvac.com/bv/bv4219.htm)
ByVacLCD bv = ByVacLCD(0x21,4,20);

// Setup TCP/IP
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 177 };
byte gateway[] = { 192, 168, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

// SRAM memory space for string management and setup WebServer service
// for send html to client
#define STRING_BUFFER_SIZE 16
char buffer[STRING_BUFFER_SIZE];

// to store data from http request
#define STRING_LOAD_SIZE 16
char load[STRING_LOAD_SIZE];

// POST and GET variables
#define STRING_VARS_SIZE 16
char vars[STRING_VARS_SIZE];

// Setup Global Vars
int countEEPROM; // Init. access count var
int cmd = 0; // Init. command var
char Domain[ ] = "www.ianjohnston.com"; // Domain or IP address
char DomainPort[ ] = "1234";  // Port if used. If not then leave blank i.e. "";
int LcdDispIO = 0; // Enable for LCD
int LcdDispIOflag = 0; // Enable for LCD flag
int seconds = 0; // Display seconds
int minutes = 0; // Display minutes
int hours = 0; // Display hours
int days = 0; // Display hours

// Setup vars for main loop scan time calculation
int scantimecounter = 0; // scan time counter
int mainloopcount = 0;
int mainloopcountold = 0;
float difference = 0; // final result in mS

// Setup Digital & Analogue I/O
// Note: Ethernet Shield reserves dig pins 10, 11, 12 & 13
int AI_Pin0 = 0;    // Ana In Ch.0 pin
int AI_Pin1 = 1;    // Ana In Ch.1 pin
int AI_Pin2 = 2;    // Ana In Ch.2 pin
int AI_Pin3 = 3;    // Ana In Ch.3 pin
// int AI_Pin4 = 4;    // Ana In Ch.4 pin / I2C
// int AI_Pin5 = 5;    // Ana In Ch.5 pin / I2C
int AI_Raw0;        // Ana In Ch.0 raw var
int AI_Raw1;        // Ana In Ch.1 raw var
int AI_Raw2;        // Ana In Ch.2 raw var
int AI_Raw3;        // Ana In Ch.3 raw var
int AI_Raw4;        // Ana In Ch.4 raw var
int AI_Raw5;        // Ana In Ch.5 raw var

int DI_Pin0 = 0;    // Dig In Ch.0 pin
int DI_Pin1 = 1;    // Dig In Ch.1 pin
int DI_Pin2 = 2;    // Dig In Ch.2 pin
int DI_Pin3 = 3;    // Dig In Ch.3 pin
int DI_Pin4 = 4;    // Dig In Ch.4 pin
int DI_Pin5 = 5;    // Dig In Ch.5 pin
int DI_Pin6 = 6;    // Dig In Ch.6 pin
int DI_Pin7 = 7;    // Dig In Ch.7 pin
int DO_Pin8 = 8;    // Dig Out Ch.8 pin (PWM to Servo)
int DO_Pin9 = 9;    // Dig Out Ch.9 pin
int DO_Pin10 = 10;  // Dig Out Ch.10 pin
int DO_Pin11 = 11;  // Dig Out Ch.11 pin
int DO_Pin12 = 12;  // Dig Out Ch.12 pin
int DO_Pin13 = 13;  // Dig Out Ch.13 pin

// Digital I/O vars
int DI_0 = 0;       // Dig In Ch.0 var
int DI_1 = 0;       // Dig In Ch.1 var
int DI_2 = 0;       // Dig In Ch.2 var
int DI_3 = 0;       // Dig In Ch.3 var
int DI_4 = 0;       // Dig In Ch.4 var
int DI_5 = 0;       // Dig In Ch.5 var
int DI_6 = 0;       // Dig In Ch.6 var
int DI_7 = 0;       // Dig In Ch.7 var
int DO_8 = 0;       // Dig Out Ch.8 var
int DO_9 = 0;       // Dig Out Ch.9 var
int DO_10 = 0;      // Dig Out Ch.10 var
int DO_11 = 0;      // Dig Out Ch.11 var
int DO_12 = 0;      // Dig Out Ch.12 var
int DO_13 = 0;      // Dig Out Ch.13 var

// Servo setup/vars
int AI_0;    // scaled var from AI_Raw0 to control the servo.


byte U1_ADDR = 33; // B0100001 = Pcb Switch setting = 001
byte U2_ADDR = 34; // B0100010 = Pcb Switch setting = 010
//byte U3_ADDR = 35; // B0100011 = Pcb Switch setting = 011
//byte U4_ADDR = 36; // B0100100 = Pcb Switch setting = 100
byte I2C_dataTx;   // Data to outputs IC's
byte I2C_dataRx;   // Data from input IC's
int I2C_TxAddr;    // IC Address holder for output
int I2C_RxAddr;    // IC Address holder for input
int i200=0;        // Demo variable only
int i200swap=0;    // Demo variable only
int delaytime=100; // Demo variable only
int ibit=0;        // Demo variable only
int bittest=0;     // Demo variable only


// setup the AI averaging formula
float AnaIY0 = (AI_Raw0);
float kana = 5;

// Strings stored in flash of the HTML we will be xmitting
#define NUM_ID 6

// Setup Flash memory vars - Command ID 2 to 6 (buttons on web page)
PROGMEM prog_char http_id1[] = "/"; // Open webpage
PROGMEM prog_char http_id2[] = "/id2";  // Web count reset button
PROGMEM prog_char http_id3[] = "/id3";  // Refresh data button
PROGMEM prog_char http_id4[] = "/id4";  // Unassigned
PROGMEM prog_char http_id5[] = "/id5";  // Unassigned
PROGMEM prog_char http_id6[] = "/id6";  // Unassigned

// Initializes TimedAction - Timer Interrupt
TimedAction Timedact01 = TimedAction(40,TimerService01);
int tick40 = 0; // 20mS Tick
int tick200 = 0; // 200mS Tick

// declare tables for the ID's.
PGM_P http_id[] PROGMEM = { http_id1, http_id2, http_id3, http_id4, http_id5, http_id6 }; // ID's

// define HTTP return structure ID for parsing HTTP header request
struct HTTP_DEF {
  int pages;
  char vars[STRING_VARS_SIZE];
} ;

Server server(80);


/***********************************************************************************************
*                                        VOID SETUP
************************************************************************************************/
void setup()
{

Wire.begin();

//Set up the LCD
bv.init();
bv.backlightOn();
bv.clear();

//digitalWrite (DO_Pin1, LOW);

Ethernet.begin(mac, ip, gateway, subnet);
server.begin();

// Assign digital I/O
pinMode(DI_Pin0, INPUT);      // sets digital pin
pinMode(DI_Pin1, INPUT);      // sets digital pin
pinMode(DI_Pin2, INPUT);      // sets digital pin
pinMode(DI_Pin3, INPUT);      // sets digital pin
pinMode(DI_Pin4, INPUT);      // sets digital pin
pinMode(DI_Pin5, INPUT);      // sets digital pin
pinMode(DI_Pin6, INPUT);      // sets digital pin
pinMode(DI_Pin7, INPUT);      // sets digital pin
pinMode(DO_Pin8, OUTPUT);     // sets digital pin
pinMode(DO_Pin9, OUTPUT);     // sets digital pin
pinMode(DO_Pin10, OUTPUT);    // sets digital pin
pinMode(DO_Pin11, OUTPUT);    // sets digital pin
pinMode(DO_Pin12, OUTPUT);    // sets digital pin
pinMode(DO_Pin13, OUTPUT);    // sets digital pin

// Servo setup
AI_0 = 512;    // Initilized at 512 (1500mS)

// EEprom setup
countEEPROM = EEPROM.read(0); // Read access count from EEprom
// EEPROM.write(0, 0); // Force reset access count to zero

}

/***********************************************************************************************
*                                         MAIN LOOP
************************************************************************************************/
void loop() {

        Client client = server.available();

        if (client) { // now client is connected to arduino
            // read HTTP header request... so select what page client are looking for
            HTTP_DEF http_def = readHTTPRequest(client);

            if (http_def.pages > 0) {
                sendPage(client,http_def);
            }
    
            // give the web browser time to receive the data
            delay(1);
            client.stop();
            while(client.status() != 0) {
            delay(5);
            } 
    
        }

        // Timed Action service
        Timedact01.check();
    
        // 200mS tick subroutine generator
        if(tick40 > 5) {
            tick40=0;
            Tick200mS(); // Jump to Tick200mS subroutine
        }
  
        scantimecounter++; // increment scan time counter

    }


/***********************************************************************************************
*                              TIMED ACTION - 40mS Interrupt Service
************************************************************************************************/
void TimerService01(){

        tick40++; // Increment tick counter. This is used to generate 200mS service.

        // Read the ana input pins  
        AI_Raw0 = analogRead(AI_Pin0);
        AI_Raw1 = analogRead(AI_Pin1);
        AI_Raw2 = analogRead(AI_Pin2);
        AI_Raw3 = analogRead(AI_Pin3);
        // AI_Raw4 = analogRead(AI_Pin4);
        // AI_Raw5 = analogRead(AI_Pin5);
        
        // Load the DI and DO vars with the I/O status of each bit
        DI_0 = digitalRead(DI_Pin0);
        DI_1 = digitalRead(DI_Pin1);        
        DI_2 = digitalRead(DI_Pin2);
        DI_3 = digitalRead(DI_Pin3);        
        DI_4 = digitalRead(DI_Pin4);
        DI_5 = digitalRead(DI_Pin5);
        DI_6 = digitalRead(DI_Pin6);
        DI_7 = digitalRead(DI_Pin7);
        DO_8 = digitalRead(DO_Pin8);
        DO_9 = digitalRead(DO_Pin9);
        DO_10 = digitalRead(DO_Pin10);
        DO_11 = digitalRead(DO_Pin11);
        DO_12 = digitalRead(DO_Pin12);
        DO_13 = digitalRead(DO_Pin13);
        
        // Generate the mS per main loop calculation. Max will be 40.00mS displayed
        if (abs(scantimecounter) != scantimecounter) // screens off problem when scantimecounter loops round
        {
            scantimecounter = 0;
            mainloopcount = 0;
            mainloopcountold = 0;
        } else {
            mainloopcountold = mainloopcount;
            mainloopcount = scantimecounter;
            if (mainloopcount > mainloopcountold) {
                difference = 40 / ((float)mainloopcount - (float)mainloopcountold); // screens off problem when scantimecounter loops round i.e. INT max = 32767
            }
        }
        
        // Process the analogue input and drive the servo. RC Servo's need updating every 20mS, but it's flexible really. 40mS will do.
        AI_0 = AI_Raw0; // map raw analogue input to AI_0
        AI_0 = map(AI_0, 0, 1023, 1000, 2000); // y=mx, 0 to 1023 scales to 1000 to 2000
        if (AI_0 < 1000) AI_0 = 1000; // Min = 1000mS
        if (AI_0 > 2000) AI_0 = 2000; // Max = 2000mS
        
        I2C_RxAddr = U2_ADDR; // set I2C address & then read the extended digital inputs
        I2C_Receive(); // run read sub
        //if (bitRead(I2C_dataRx, 2) == 0) { // Check bit 2 and if pressed send servo to minimum position
        //  AI_0 = 1000;
        //}
        //if (bitRead(I2C_dataRx, 3) == 0) { // Check bit 3 and if pressed send servo to maximum position
        //  AI_0 = 2000;
        //}
        
        //AI_0 = AI_0 + 10;
        //if (AI_0 > 1999) AI_0 = 1000;
        digitalWrite(DO_Pin8, HIGH);   // Turn the motor on
        delayMicroseconds(AI_0);       // Length of the pulse sets the motor position
        digitalWrite(DO_Pin8, LOW);    // Turn the motor off
        
    } // End TimerService01

    
/***********************************************************************************************
*                                         200mS Service
************************************************************************************************/
void Tick200mS(){ // This routine runs once every 200mS    

        // Test
        if (DI_6 == 1) {
        digitalWrite (DO_Pin9, HIGH);
        } else {
        digitalWrite (DO_Pin9, LOW);
        }

         int i;

        // This is a test of a wee analogue averaging formula I found. Testing on AI_Raw0
        // Am running it under a fixed service as I think it will be affected too much otherwise
        // Yn=Yn+(1/kana*(Xn-Yn)) // Averaging formula
        // Xn = AI_Raw0
        // Yn = AnaIY0
        // kana = constant
        AnaIY0 = AnaIY0 + (1 / kana * ((float)AI_Raw0 - AnaIY0));

        // Generate UpTime days:hrs:mins:secs
        if(++tick200 > 4) { // 4 means every 1000mS
        tick200 = 0;
            if(++seconds > 59) {
                if(++seconds > 59) {
                    seconds = 0;
                    ++minutes;
                    if (minutes > 59) {
                        ++hours;
                        minutes=0;
                        if (hours > 23) {
                          ++days;
                          hours=0;
                            if (days > 9999) {
                              days=0;
                            }
                        }                
                    }
                }          
            } 
        } 
        
        // Toggle round I/O on LCD
        if (DI_7 == 1) {
            LcdDispIO++;
            LcdDispIOflag = 1; // Set up flag to notify change of screen
            if (LcdDispIO == 5) {
                LcdDispIO = 0;
            }
        }
    
        if (LcdDispIO == 0) {
            if (LcdDispIOflag == 1) { // only clear LCD on a change of screen
                bv.clear();
                LcdDispIOflag = 0;
            }
            
            bv.setCursor(0,0);
            bv.print(" Arduino Web Server ");
            bv.setCursor(2,1);
            bv.print(difference); bv.print("mS main loop"); bv.print(" "); 
            bv.setCursor(0,2);
            bv.print("    Access's="); bv.print(countEEPROM);
            if (countEEPROM == 0) {
                bv.setCursor(14,2); bv.print("     ");
            }
        }

        if (LcdDispIO == 1) {
            if (LcdDispIOflag == 1) { // only clear LCD on a change of screen
                bv.clear();
                LcdDispIOflag = 0;
            }
            bv.setCursor(0,0); bv.print("ANALOGUE INPUTS RAW");
            bv.setCursor(0,1); bv.print("0="); bv.print(AI_Raw0); bv.print("  ");
            bv.setCursor(7,1); bv.print("3="); bv.print(AI_Raw3); bv.print("  ");
            bv.setCursor(0,2); bv.print("1="); bv.print(AI_Raw1); bv.print("  ");
            bv.setCursor(0,3); bv.print("2="); bv.print(AI_Raw2); bv.print("  ");
            bv.setCursor(14,1); bv.print("A="); bv.print(int(AnaIY0)); bv.print(" "); // Testing only - The averaged copy of AI_Raw0
            bv.setCursor(14,2); bv.print("S="); bv.print(int(AI_0)); // Testing only - Servo1 output mS
            bv.setCursor(18,3); bv.print("mS"); // Testing only - Servo1 output mS
        }

        if (LcdDispIO == 2) {
            if (LcdDispIOflag == 1) { // only clear LCD on a change of screen
                bv.clear();
                LcdDispIOflag = 0;
            }
            bv.setCursor(0,0); bv.print("   DIGITAL INPUTS   ");
            bv.setCursor(0,1); bv.print("Ch.0 1 2 3 4 5 6 7  ");
            bv.setCursor(3,2); bv.print(DI_0);
            bv.setCursor(5,2); bv.print(DI_1);
            bv.setCursor(7,2); bv.print(DI_2);
            bv.setCursor(9,2); bv.print(DI_3);
            bv.setCursor(11,2); bv.print(DI_4);
            bv.setCursor(13,2); bv.print(DI_5);
            bv.setCursor(15,2); bv.print(DI_6);
            bv.setCursor(17,2); bv.print(DI_7);
        }
        
        if (LcdDispIO == 3) {
            if (LcdDispIOflag == 1) { // only clear LCD on a change of screen
                bv.clear();
                LcdDispIOflag = 0;
            }
            bv.setCursor(0,0); bv.print("  DIGITAL OUTPUTS   ");
            bv.setCursor(0,1); bv.print("Ch.8 9 10 11 12 13  ");
            bv.setCursor(3,2); bv.print(DO_8);
            bv.setCursor(5,2); bv.print(DO_9);
            bv.setCursor(7,2); bv.print(DO_10);
            bv.setCursor(10,2); bv.print(DO_11);
            bv.setCursor(13,2); bv.print(DO_12);
            bv.setCursor(16,2); bv.print(DO_13);
        }

        
        if (LcdDispIO == 4) {
            if (LcdDispIOflag == 1) { // only clear LCD on a change of screen
                bv.clear();
                LcdDispIOflag = 0;
            }
            bv.setCursor(0,0);    bv.print("    I2C TESTING     ");  // Will ONLY do the I2C stuff when I2C screen is selected
            
            // Demo rotate round all 8off bits on U1 turning them on one by one, one change per run of this loop
            if (i200swap == 0) {
              I2C_TxAddr = U1_ADDR; // Set I2C address to send to
              bitSet(I2C_dataTx, i200);
              I2C_Send(); // Run subroutine and send data to I2C bus
              i200++;
              if (i200 == 8) {
                i200 = 0;        
                i200swap = 1;
              }
            }
        
            if (i200swap == 1) {
              I2C_TxAddr = U1_ADDR; // Set I2C address to send to
              bitClear(I2C_dataTx, i200);
              I2C_Send(); // Run subroutine and send data to I2C bus
              i200++;
              if (i200 == 8) {
                i200 = 0;        
                i200swap = 0;
              }
            }            

            bv.setCursor(0,1); bv.print("U2 Rx bits=");
            I2C_RxAddr = U2_ADDR; // set I2C address
            I2C_Receive(); // Run subroutine and receive data from I2C bus, data appears in var I2C_dataRx.
              for(i = 0; i < 7; i++) {
                bv.setCursor(ibit+11,1);
                bittest = (bitRead(I2C_dataRx,ibit));
                bv.print(bittest);
                ibit++;
                  if (ibit == 8) {
                    ibit = 0;        
                  }
            }
            
        }
            
            
        if (LcdDispIO == 0) {  // Updated every 1sec via tick250
            bv.setCursor(0,3);
            bv.print("Uptime=");  // A pity the Arduino language doesn't have a flag for this!...such as cout << setfill('0') << setw(2) << second;
            if (days == 0) {
                bv.setCursor(7,3);
                bv.print("0000"); bv.print(":");
                } else if (days < 10) {
                bv.setCursor(7,3);    bv.print("000"); bv.print(days); bv.print(":");
                } else if (days < 100) {
                bv.setCursor(7,3);    bv.print("00"); bv.print(days); bv.print(":");
                } else if (days < 1000) {
                bv.setCursor(7,3);    bv.print("0"); bv.print(days); bv.print(":");
                } else if (days < 10000) {
                bv.setCursor(7,3);    bv.print(days); bv.print(":");
            }
                
                if (hours == 0) {
                    bv.setCursor(12,3);
                    bv.print("00");  bv.print(":");
                    } else if (hours < 10) {
                    bv.setCursor(12,3); bv.print("0"); bv.print(hours); bv.print(":");
                    } else if (hours < 100) {
                    bv.setCursor(12,3); bv.print(hours); bv.print(":");    
                }                        

                if (minutes == 0) {
                    bv.setCursor(15,3);
                    bv.print("00");  bv.print(":");
                    } else if (minutes < 10) {
                    bv.setCursor(15,3); bv.print("0"); bv.print(minutes);    bv.print(":");    
                    } else if (minutes < 100) {
                    bv.setCursor(15,3); bv.print(minutes);    bv.print(":");                    
                }    

                if (seconds == 0) {
                    bv.setCursor(18,3);
                    bv.print("00");
                    } else if (seconds < 10) {
                    bv.setCursor(18,3); bv.print("0"); bv.print(seconds);
                    } else if (seconds < 100) {
                    bv.setCursor(18,3); bv.print(seconds);
                }
                
        }
        
    
    }

    
/***********************************************************************************************
*                        Method for read HTTP Header Request from web client
************************************************************************************************/
struct HTTP_DEF readHTTPRequest(Client client) {
  char c;
  int i;

  // use buffer
  int bufindex = 0; // reset buffer
  int loadindex = 0; // reset load

  int contentLength = 0; // reset POST content Length
  char compare[50]; // page comparison (ID selection)

  HTTP_DEF http_def; // use structure for multiple returns

  // reading all rows of header
  if (client.connected() && client.available()) { // read a row
    buffer[0] = client.read();
    buffer[1] = client.read();
    bufindex = 2;
    // read the first line to determinate the request page
    while (buffer[bufindex-2] != '\r' && buffer[bufindex-1] != '\n') { // read full row and save it in buffer
      c = client.read();
      if (bufindex<STRING_BUFFER_SIZE) buffer[bufindex] = c;
      bufindex++;
    }

    // select the page from the buffer (GET and POST) [start]
    for(i = 0; i < NUM_ID; i++) {
      strcpy_P(load, (char*)pgm_read_word(&(http_id[i])));
      
      // GET
      strcpy(compare,"GET ");
      strcat(compare,load);
      strcat(compare," ");
      if (strncmp(buffer,compare, strlen(load)+5)==0) {
        http_def.pages = i+1;
            if (http_def.pages > 1) { // If it's not 0 or 1 then it's not a page being requested, rather a button command
            cmd = http_def.pages; // command from webpage to action            
            http_def.pages = 1; // This sets the page requested to default 1.
            }
        break;
      }

      // POST
      strcpy(compare,"POST ");
      strcat(compare,load);
      strcat(compare," ");
      if (strncmp(buffer,compare, strlen(load)+6)==0) {
        http_def.pages = i+1;
            if (http_def.pages > 1) { // If it's not 0 or 1 then it's not a page being requested, rather a button command
            cmd = http_def.pages; // command from webpage to action            
            http_def.pages = 1; // This sets the page requested to default 1.
            }
        break;
      }

    }

 // clean buffer for next row
    bufindex = 0;
  }

 // strncpy(http_def.vars,vars,STRING_VARS_SIZE);  // Copy from vars to http_def.vars length STRING_VARS_SIZE - Uncommenting this causes html to be corrupted at client?
  
  return http_def;

 }

 
/***********************************************************************************************
*                                        I2C Subs
************************************************************************************************/ 
 void I2C_Send() {
  // I2C send routine
  Wire.beginTransmission(I2C_TxAddr); // setup I2C address to send to
  Wire.send(I2C_dataTx);              // send byte to that address
  Wire.endTransmission();             // end send
} 
void I2C_Receive() {
  // I2C receive routine
  Wire.requestFrom(I2C_RxAddr, 1);    // request 1 byte from I2C address
  if (Wire.available()) I2C_dataRx = Wire.receive();
  //I2C_dataRx = Wire.receive();        // receive a byte as character
} 

  
/***********************************************************************************************
*                                   SEND WEB PAGE TO BROWSER
************************************************************************************************/
void sendPage(Client client,struct HTTP_DEF http_def) {

        // CMD's 0 & 1 are reserved, they are the full page refresh
        
        // No CMD button, user has come in straight onto page via root addr so update counter
        if (cmd == 0) {
            // Increment page access counter
            countEEPROM++;
            if (countEEPROM > 9999) { // Maximum count = 9999
                countEEPROM = 9999;
            } 
            EEPROM.write(0, countEEPROM);  // write current access count to EEprom
        } 

        // CMD button 2 RESET COUNT has been pressed on the web page
        if (cmd == 2) {
            countEEPROM = 0;
            EEPROM.write(0, countEEPROM);
        } 
        
        if (http_def.pages==0 || http_def.pages==1) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();
            client.print("<html><head><title>IanJ's Arduino Web Server</title></head>");
            client.print("<p>"); 
            client.print("<table width=800 border=1 cellspacing=0 cellpadding=4>");
            client.print("<tr><td align=middle colspan=3>");
            client.print("<table width=100% border=0 cellspacing=0 cellpadding=0><tr><td align=left width=200>");
            client.print("<form method=\"post\" NAME=\"refresh\" action=\"http://");
            client.print(Domain); client.print(":"); client.print(DomainPort); client.print("/");
            client.print("id3\" NAME=\"id3\">");
            client.print("<button name=\"submit2\" value=\"button2\" type=\"submit\">Refresh Data</button></form>");
            client.print("</td><td align=middle width=600><font size=+2><b>IanJ's Arduino Web Server</b></font></td>");
            client.print("<td width=200>.</td></tr></table>");
            client.print("</td></tr>");
            client.print("<tr><td width=33% height=200 valign=top>");
            client.print("<b>Stats:</b>");  
            client.print("<br>");  
            client.print("Uptime = "); client.print(days); client.print("days "); client.print(hours); client.print("hrs ");  client.print(minutes); client.print("mins ");  client.print(seconds); client.print("secs");
            client.print("<br>");
            client.print("<form method=\"post\" action=\"http://");
            client.print(Domain); client.print(":"); client.print(DomainPort); client.print("/");
            client.print("id2\" NAME=\"id2\">");
            client.print("Page access's = "); client.print(countEEPROM); 
            client.print(" "); 
            client.print("<BUTTON name=\"submit\" value=\"button\" type=\"submit\">Reset</button></form>");
            client.print("<br>");
            client.print(difference); client.print("mS Main Loop");
            client.print("</td><td width=33% align=center valign=middle><img src=\"http://"); client.print(Domain); client.print("/Arduino/ArduinoLcd.jpg\">");
            client.print("</td><td width=33% valign=top>");
            client.print("Atmeg328 16Mhz<br>32k Flash<br>2k SRAM<br>");
            client.print("1k EEprom<br>Dig I/O = 14<br>AI = 6off (10bit)<br>I2C Bus");
            client.print("</td></tr>");
            client.print("<tr><td align=middle colspan=3><i>by Ian Johnston</i></td></tr>");
            client.print("</table>");
            client.print("</html>");
            
            cmd = 0; // reset CMD back to zero
        } 


    }



 

Powered by Joomla CMS.  JA_Purity_II template modded by Ian.J