0

Here is my code:

#include <SPI.h>
#include <OneWire.h>
#include <EthernetV2_0.h>
#include <EthernetClientV2_0.h>
#include <EthernetServerV2_0.h>
#include <EthernetUdpV2_0.h>
#include <math.h>
#include <Client.h>
#include <WString.h>
     #include <stdlib.h>
#include <OneWire.h>
#include <stdio.h>
#include <DhcpV2_0.h>
#include <DnsV2_0.h>

int whiteLevel;
int colorLevel;
int blueLevel;
int standardLightingPattern[3] = { 200, 160, 250 };
int twilightLightingPattern[3] = { 20, 50, 100 };
int nightTimeLightingPattern[3] = { 0, 10, 40 };
int morningLightingPattern[3] = { 50, 50, 100 };
int deepNightLightingPattern[3] = { 0, 20, 80 };
int feedingLightingPattern[3] = { 20, 20, 50 };
int i;
int j;
char *buildUrlParameter(float ph, float temp1, float temp2);

// Pin Delcarations
int temperaturePins[2] = { 30,31 };
int outletPins[] = { 22, 23, 24, 25, 26, 27 };
const int whiteLedString = 44;    // connected to LDD-700HW on white strand
const int colorLedString = 45;    // connected to LDD-1000HW on color strand
const int blueLedString = 46;     // connected to LDD-1000HW on royal blue     strand

// Sensor Variables
float temps[2];
String sensorstring = "";
boolean sensor_string_complete = false;
float pH;


// Variables for URL char buffer
char outBuf[100];
char charBuf[6];
char cnctPh[6];
char cnctTemp1[7];
char cnctTemp2[7];
char urlParameter[34];
char dest1[34];

//char serverIP[] = "74,125,224,80";
//char serverIP[] = "192.168.1.107";
//char serverIP[] = "www.arduino.cc";

// assign a MAC address for the ethernet controller.
// fill in your address here:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
// fill in an available IP address on your network here,
// for manual configuration:
IPAddress ip(192,168,1,199);

// fill in your Domain Name Server address here:
IPAddress myDns(8,8,8,8);

// initialize the library instance:
EthernetClient client;

char server[] = "192.168.1.107";

unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000;  // delay between updates, in milliseconds
#define W5200_CS  10
#define SDCARD_CS 4
void setup() {
   // start serial port:
 Serial.begin(38400);
 Serial3.begin(38400);
 pinMode(SDCARD_CS,OUTPUT);
  digitalWrite(SDCARD_CS,HIGH);//Deselect the SD card
  // give the ethernet module time to boot up:
   delay(1000);
  // start the Ethernet connection using a fixed IP address and DNS server:
  Ethernet.begin(mac, ip, myDns);
  // print the Ethernet board/shield's IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
}

void loop() {
  char c;
  dimLights(standardLightingPattern);
  dimLights(nightTimeLightingPattern);


  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime >    postingInterval)) {
    getPh();
    getTemperature();
    httpRequest();
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}


void getPh() {
  Serial3.print("r<CR>");
  if (sensor_string_complete == true) {
   //Serial.println(sensorstring);
   if (isdigit(sensorstring[0])) {
      pH = sensorstring.toFloat();
    }
  }

 sensorstring = "";
 sensor_string_complete = false;
}

void dimLights(int lightingBrightnessArray[]) {
  analogWrite(whiteLedString, lightingBrightnessArray[0]);
  analogWrite(colorLedString, lightingBrightnessArray[1]);
  analogWrite(blueLedString, lightingBrightnessArray[2]);

}

float getTemp(int pin) {
  OneWire ds(pin);
  byte k;
  byte present = 0;
  byte type_s = 0;
  byte data[12];
  byte addr[8];
  float celsius;
  float fahrenheit;

  if (!ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(2500);
  }

  ds.reset();
  ds.select(addr);

  // start conversion, with parasite power on at the end
  ds.write(0x44, 1);

  // maybe 750ms is enough, maybe not  
  delay(1000);

  present = ds.reset();
  ds.select(addr);

  // Read Scratchpad
  ds.write(0xBE);

  // we need 9 bytes
  for (k = 0; k < 9; k++) {
    data[k] = ds.read();
  }

  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {

   // 9 bit resolution default
   raw = raw << 3;

   if (data[7] == 0x10) {
     // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
    } else {
      byte cfg = (data[4] & 0x60);
      // at lower res, the low bits are undefined, so let's zero them
      if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
      else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
      else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms

     // default is 12 bit resolution, 750 ms conversion time
    }

    celsius = (float)raw / 16.0;
    fahrenheit = celsius * 1.8 + 32.0;
    return fahrenheit;
}

void getTemperature() {

 //get temperature 1 from display
  temps[0] = getTemp(temperaturePins[0]);
  delay(1000);

  //get temperature 2 from sump
  temps[1] = getTemp(temperaturePins[1]);
  delay(1000);

  //used for building parameters for GET request for passing DB values
  Serial.println("");
  float temp1 = temps[0];
  float temp2 = temps[1];
  //converts pH sensor char buffer to float val
  //float pH = atof(stamp_data);  

  //used for debugging
  Serial.println("Returned Temp 1: ");
  Serial.println(temp1);
  Serial.println("Returned Temp 2: ");
  Serial.println(temp2);
  Serial.println("ph val:");
  Serial.println(pH);

  //build url for GET request using above parameters
  *buildUrlParameter(pH, temp1, temp2);
  Serial.println(dest1);
  //make HTTP request
   httpRequest();
}

char *buildUrlParameter(float pH, float temp1, float temp2) {
  //builds char buffer from three float values passed from  
  //sensors and apends proper sensor monikers
  dtostrf(pH, 4, 2, cnctPh);
  dtostrf(temp1, 5, 2, cnctTemp1);
  dtostrf(temp2, 5, 2, cnctTemp2);
  strcpy(dest1, "ph=");
  strcat(dest1, cnctPh);
  strcat(dest1, "&T1=");
  strcat(dest1, cnctTemp1);
  strcat(dest1, "&T2=");
  strcat(dest1, cnctTemp2);

  return dest1;
}

 // this method makes a HTTP connection to the server:
   void httpRequest() {

   sprintf(outBuf, "GET http://192.168.1.107/ReefController/trunk/app/php/reef_controller_loadVals_all.php?%s HTTP/1.0", dest1);
   Serial.println(outBuf);
//Serial.println("connecting...");
 delay(1000);
  //client.connect(server, 80);

  // if there's a successful connection:
  if (client.connect(server, 80)) {
    client.println(outBuf);
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.println("Host: localhost");
    client.println("User-Agent: arduino-ethernet");
    client.println("Content Type: application/json");
    client.println("Connection: close");
    client.println();


    Serial.println("Successfully recorded to database");
    // note the time that the connection was made:
    lastConnectionTime = millis();
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println("disconnecting.");
    client.stop();
  }
}`

What is happening is when my program hits httpRequest the client.connect is successful maybe 2-3 times out of 5. The PHP server is up and running fine. It will just fall into the last else and give me connection failed / disconnecting when it isn't working.... when it does work I get a response back 500 internal server error yet the PHP script runs and records my posted values to the database. Any thoughts?

  • If i put client.stop: ` // if you're not connected, and ten seconds have passed since // your last connection, then connect again and send data: if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) { getPh(); getTemperature(); httpRequest(); }` I seem to have better results but I am not sure why I would need to stop the client after an httpRequest. – VinnyGuitara Jan 18 '16 at 23:53
  • You need to stop the socket connection when you are done, in order for the server to successfully close the connection and also to free file handles, i think. In your GET request, get rid of the IP address; start with /ReefCont...also get rid of the other header fields in your GET request, and try again – TisteAndii Jan 19 '16 at 10:32
  • @brianrho good point, I had not even seen the part where he adds the other headers. With HTTP1.0 you can get away with nothing more than just the GET line. If you want to keep the other headers do not forget to add \r\n after each line. – larzz11 Jan 19 '16 at 12:42
  • @brianrho do I not need the ip in my get because I'm already connected to that server? – VinnyGuitara Jan 19 '16 at 12:46
  • Exactly. You are already connected. – TisteAndii Jan 19 '16 at 12:53
1

This is why I think the server returns a HTTP500:

Usually in HTTP requests you do not include the ip address, so:

GET http://192.168.1.107/<really long part>?%s HTTP/1.0

would become:

GET /<really long part>?%s HTTP/1.0

Also HTTP requests should use carriage return AND line feed to indicate the end of a line. And an HTTP request should ALWAYS end in a full blank line. You are using the HTTP1.0 protocol, so your request can be done in one line, so you can just end it with: \r\n\r\n. If your request would be multiple lines, every line should also end with \r\n.

So the result would be:

GET /<really long part>?%s HTTP/1.0\r\n\r\n

One CRLF (the \r\n part) to begin a new line and one more for the blank line.

As for the connection problem, I think this has to do with the fact that you need to open AND close the connection for each HTTP request. You are using the HTTP1.0 protocol which does not support multiple HTTP requests in one connection. You can send multiple HTTP requests when using HTTP1.1, but then you also have to think about the TCP keepalive and it makes your request more complicated.

Try changing your HTTP request as mentioned above and call client.connect() and a client.stop() for every HTTP request. And don't forget to tell us the results!

  • Great thanks @larzz11. I am going to try this when I eat home from work tonight. It's 730am in my time zone right now. I'll update once I try it. – VinnyGuitara Jan 19 '16 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.