Air Quality Meter

/*
  Air Quality meter
  Language: Wiring/Arduino (pin numbers defined for Arduino)

  Microcontroller is connected to a Lantronix serial-to-ethernet device. This program connects to a HTTP server through the Lantronix module, makes a HTTP GET request for a PHP script, and parses the returned string.
  Lantronix device communicates at 9600-8-n-1 non-inverted (true) serial.
  Lantronix serial settings:
  Baudrate 9600, I/F Mode 4C, Flow 00
  Port 10001
  Remote IP Addr: --- none ---, Port 00000
  Connect Mode : D4
  Disconn Mode : 00
  Flush   Mode : 00
 */

// Defines for the  program's status (used for status variable):
#define disconnected 0
#define connecting 1
#define connected 2
#define requesting 3
#define reading 4
#define requestComplete 5

// Defines for I/O pins:

#define connectedLED 2        // indicates when there's a TCP connection
#define requestingLED 3       // indicates a HTTP request has been made
#define readingLED 4          // indicates device is reading HTTP results
#define requestCompleteLED 5  // indicates a successful read
#define programResetLED 6     // indicates reset of Arduino
#define deviceResetPin 7      // resets Lantronix Device
#define meterPin 11           // controls VU meter

// defines for voltmeter:
#define meterMax 130          // max value on the meter
#define meterScale 150        // my meter reads 0 - 150

// variables:
int inByte= -1;              // incoming byte from serial RX
char inString[32];           // string for incoming serial data
int stringPos = 0;           // string index counter

int status = 0;              // Lantronix device's connection status
long lastCompletionTime = 0; // counter for delay after last completion

void setup() {
  // set all status LED pins and Lantronix device reset pin:
  pinMode(connectedLED, OUTPUT);
  pinMode(requestingLED, OUTPUT);
  pinMode(requestCompleteLED, OUTPUT);
  pinMode(programResetLED, OUTPUT);
  pinMode(deviceResetPin, OUTPUT);
  pinMode(meterPin, OUTPUT);

  // start serial port, 9600 8-N-1:
  Serial.begin(9600);
  //reset Lantronix device:
  resetDevice();
  // blink reset LED:
  blink(3);
}

void loop() {
  stateCheck();
  setLEDs();
}

/*
  Check the status of the connection and take appropriate action:
 /*

void stateCheck() {
  switch (status) {
  case disconnected:
    // attempt to connect to the server:
    deviceConnect();
    break;
  case connecting:
    // until you get a C, keep trying to connect:
    // read the serial port:
    if (Serial.available()) {
      inByte = Serial.read();
      if (inByte == 'C') {  // 'C' in ascii
        status = connected;
      }
      else {
        // if you got anything other than a C, try again:
        deviceConnect();
      }
    }
    break;
  case connected:
    // send HTTP GET request for CGI script:
    httpRequest();
    break;
  case requesting:
    lookForData();
    break;
  case reading:
    readData();
    break;
  case requestComplete:
    waitForNextRequest();
  }
}

/*
  Set the indicator LEDs according to the state of the program
 /*

void setLEDs() {
  /*  Except for the disconnected and connecting states,
   all the states of the program have corresponding LEDS.
   so you can use a for-next loop to set them  by
   turning them all off except for the one that has
   the same number as the current program state:
   /*

  for (int thisLED = 2; thisLED <= 5; thisLED++) {
    if (thisLED == status) {
      digitalWrite(thisLED, HIGH);
    }
    else {
      digitalWrite(thisLED, LOW);
    }
  }
}

/*
  Command the Lantronix device to connect to the server
 /*

void deviceConnect() {
  //   fill in your server's numerical address below:
  Serial.print("C82.165.199.35/80\n");
  status = connecting;
}

/*
  Send a HTTP GET request
 /*

void httpRequest() {
  // make sure you've cleared the last byte
  // from the last request:
  inByte = -1;
  // reset the string position counter:
  stringPos = 0;
  //  Make HTTP GET request. Fill in the path to your version
  //  of the CGI script:
  Serial.print("GET /~myaccount/scraper.php HTTP/1.0\n");
  //  Fill in your server's name:
  Serial.print("HOST:example.com\n\n");
  // update the state of the program:
  status = requesting;
}

/*
  Read the results sent by the server until you get a < character.
 /*

void lookForData() {
  // wait for bytes from server:
  if (Serial.available()) {
    inByte = Serial.read();
    // If you get a "<", what follows is the air quality index.
    // You need to read what follows the <.
    if (inByte == '<') {
      stringPos = 0;
      status = reading;
    }
  }
}
/*
  read the number from the server into an array, terminating with a > character.
 /*

void readData() {
  if (Serial.available()) {
    inByte = Serial.read();
    // Keep reading until you get a ">":
    if (inByte != '>') {
      // save only ASCII numeric characters (ASCII 0 - 9):
      if ((inByte >= '0') && (inByte <= '9')){
        inString[stringPos] = inByte;
        stringPos++;
      }
    }
    // if you get a ">", you've reached the end of the AQI reading:
    else {
      interpretResults();
    }
  }
}

/*
  convert the input string to an integer.
 /*

void interpretResults() {
  // convert the string to a numeric value:
  int airQuality = atoi(inString);
  // set the meter appropriately:
  setMeter(airQuality);
  lastCompletionTime = millis();
  status = requestComplete;
}
/*
  scale the number from the request to the meter's range and set the meter.
 /*

void setMeter(int desiredValue) {
  int airQualityValue = 0;
  // if the value won't peg the meter, convert it
  // to the meter scale and send it out:
  if (desiredValue <= meterScale) {
    airQualityValue = (desiredValue * meterMax /meterScale) ;
    analogWrite(meterPin, airQualityValue);
  }
}

/*
  Wait two minutes before initiating a new request.
 /*

void waitForNextRequest() {
  if (millis() - lastCompletionTime >= 120000) {
    // reset Lantronix device before next request:
    resetDevice();
    status = disconnected;
  }
}

/*
  Take the Lantronix device's reset pin low to reset it
 /*

void resetDevice() {
  digitalWrite(deviceResetPin, LOW);
  delay(50);
  digitalWrite(deviceResetPin, HIGH);
  // pause to let Lantronix device boot up:
  delay(2000);
}
/*
   Blink the reset LED.
 /*

void blink(int howManyTimes) {
  int i;
  for (i=0; i< howManyTimes; i++) {
    digitalWrite(programResetLED, HIGH);
    delay(200);
    digitalWrite(programResetLED, LOW);
    delay(200);
  }
}