Go Down

Topic: Issue calling PHP using Ethernet Shield (Read 1 time) previous topic - next topic

PaulS

Quote
Because I am using an Ethernet Shield, pins 10-13 cannot be used for standard outputs, so i decided to use pins 8 & 9 as my outputs instead.

You won't be able to use the led on pin 13, either.

Quote
Nothing was changed other than specifying the new startPin and stopPin variables:

#define startPin 8               // The first pin we connect a relay to
#define stopPin 9                // The last pin we connect a relay to

and changing the 'if (pinNum == 8 )' statements.

Why isn't the if statement
Code: [Select]
if (pinNum == startPin)
?

Quote
Unfortunatly the PHP is now not being called and just states 'failed to call PHP' in the serial debug window.

Pin 10 is not now being set as an OUTPUT pin, in setup(). Even if you do not want to deselect the ethernet shield, you must define pin 10 as OUTPUT for the ethernet shield to work.

Quote
Having read the tutorial on arrays, i'm still not fully understanding them, but i guess I need the array to be more flexible to allow for flexibility in the length of the ident string and also for a 1 or 2 digit pin number.  This is what was attempted to be achieved in the initial code variation.

Your failure to connect to the internet has nothing to do with parsing the data that you get from virtual wire.

Tissy

Thanks for your reply and help Paul.

Quote

You won't be able to use the led on pin 13, either.

This has now been moved to a different pin

Quote

Why isn't the if statement
if (pinNum == startPin)

Because ultimately I will have 4 alarm conditions, so for now I thought it easier to define them that way opposed to using variables.  However, I have renamed the 2 if statements using the startPin & stopPin variables for ease whilst testing.

Quote

Pin 10 is not now being set as an OUTPUT pin, in setup(). Even if you do not want to deselect the ethernet shield, you must define pin 10 as OUTPUT for the ethernet shield to work.

I did think this may be an issue, however setting these pins (10-12) to OUTPUT in setup() has made no difference.  In all examples I've seen using the Ethernet shield I have not seen the requirement to set these pins manually.

It seems to ouput the "failed to call PHP" instantly as if its not really even attempting to call it.

Any other suggestions ?

PaulS

Only pin 10 needs to be set as an OUTPUT. The SPI code that the ethernet shield uses to communicate with the Arduino knows how to deal with the other pins. It may be necessary to actually set the pin (10) HIGH, too.

Tissy

This is driving me nuts and seems to defy all logic  :0

The main code below doesn't work and prevents the PHP from being called.

However, if i comment out this section, it works fine ??

I've stripped out as much as i can for testing only leaving a simple loop.

Could something in the RF receiver section be causing problems ?  Seems weird if it is, but commenting it out resolves the issue.

Code: [Select]

  //Set-up the RF receiver
//  vw_setup(1000);                     // Bits per sec
//  vw_set_rx_pin(rxPin);               // We will be receiving on pin 2 ie the RX pin from the module connects to this pin.
//  vw_rx_start();                      // Start the receiver


Code: [Select]

static String ident = "server";     // Identification for this device

#include <SPI.h>
#include <Ethernet.h>               // Ethernet Library
#include <DHT.h>                    // DHT Temp & Humidity Library
#include <VirtualWire.h>            // 433Mhz Module Library

byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x79, 0xED };    // Arduino MAC Address
byte ip[] = { 192,168,1,142 };                          // local Arduino IP
//byte gateway[] = { 192,168,1,1 };                     // IP of Gateway
//byte subnet[] = { 255, 255, 255, 0 };                 // Subnet Address
byte server[] = { 192,168,1,101 };                      // IP of Web Server

Client client(server, 80);

const int ledPin =  6;            // The number of the LED pin, LED used to indicate we got a message
long onMillis = 0;                 // Will store last time LED was updated

// *** Uncomment whatever type of Temp sensor being used ***
#define DHTTYPE DHT11              // DHT 11
#define DHTPIN 5                   // Sets DHT Temp Sensor Pin

// *** Set-up Temperature Sensor ***
DHT dht(DHTPIN, DHTTYPE);

// *** Fan related Variables ***
#define fanPin 7                   // Fan is connected to PIN 5

// *** Temperature Variables ***
#define maxTemp 35                 // Fan will start at this temperature
#define minTemp 32                 // Sets Temp Hysteresis variation (3 degress) 

// *** RF Variables ***
#define rxPin 3                    // Sets 433Mhz Rx Pin

// *** Other Variables ***
#define startPin 8               // The first pin we connect a relay to
#define stopPin 9                // The last pin we connect a relay to

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
 
    pinMode(10, OUTPUT);
    digitalWrite(10, HIGH);   
   
//    pinMode(11, OUTPUT);
//    digitalWrite(11, HIGH);   
   
    pinMode(12, OUTPUT);
    digitalWrite(12, HIGH); 
 
  //Set-up the RF receiver
  vw_setup(1000);                     // Bits per sec
  vw_set_rx_pin(rxPin);               // We will be receiving on pin 2 ie the RX pin from the module connects to this pin.
  vw_rx_start();                      // Start the receiver

  dht.begin();  // Begin reading DHT sensor
 
  // Set necessary Pins for OUTPUT and set their initial state
  for (int i = startPin; i <= stopPin; i++)
  {
    Serial.print("Setting pinMode on pin: ");
    Serial.println(i);
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);   
  }
  Serial.println("Ready to receive!");
}

void loop()
{
  alarm_1();
  delay(5000);
  alarm_2();
  delay(5000);
}

void alarm_1(){
  unsigned long startTime = millis();

  if (client.connect()) { //connect to server
      Serial.println("connected to server");
      // Make a HTTP request:
      client.println("GET /alarm_1.php");               // location of ProwlPHP script
//     client.println("Host: tisseyre.homeserver.com");           // domain name
//     client.println("Connection: close");                       // this line is not related to your problem but I recommend it ;)
      client.println();
      delay(1000);
  }
  else {
    Serial.println("failed to call PHP");
  }
    delay(1000);
    Serial.print("Response from server: ");
    while ((!client.available()) && ((millis() - startTime ) < 5000));
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
 
    // if the server's disconnected, stop the client:
    if (!client.connected()) {
      Serial.println("disconnecting from server");
//      client.println("Connection: close");                       // this line is not related to your problem but I recommend it ;)
      client.stop();
      client.flush();
      Serial.println("Disconnected...");
    }
}

void alarm_2(){
  unsigned long startTime = millis();

  if (client.connect()) { //connect to server
      Serial.println("connected to server");
      // Make a HTTP request:
      client.println("GET /alarm_2.php");               // location of ProwlPHP script
      client.println("Host: tisseyre.homeserver.com");           // domain name
      client.println("Connection: close");                       // this line is not related to your problem but I recommend it ;)
      client.println();
      delay(1000);
  }
  else {
    Serial.println("failed to call PHP");
  }
    delay(1000);
    Serial.print("Response from server: ");
    while ((!client.available()) && ((millis() - startTime ) < 5000));
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
 
    // if the server's disconnected, stop the client:
    if (!client.connected()) {
      Serial.println("disconnecting from server");
//      client.println("Connection: close");                       // this line is not related to your problem but I recommend it ;)
      client.stop();
      client.flush();
      Serial.println("Disconnected...");
    }
}

void temperature (){
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float humidity = dht.readHumidity();
  float temp = dht.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(temp) || isnan(humidity)) {
    Serial.println("Failed to read from DHT");
  } else {
    if (temp >= maxTemp){
        Serial.print("Temperature: ");
        Serial.print(temp);
        Serial.println(" *C"); 
    fan(true);}
    else if (temp <= minTemp)
    {fan(false);}
  }
  if (temp <= maxTemp && temp >= minTemp){
        Serial.print("Temperature: ");
        Serial.print(temp);
        Serial.println(" *C");}
}
   
void fan(boolean stat){
  digitalWrite(fanPin, stat);
}

PaulS

Code: [Select]
    pinMode(12, OUTPUT);
    digitalWrite(12, HIGH); 

I don't think you want to do this.

Tissy

I forgot to remove that line  :smiley-red:

However, with that removed, the program still doesn't work unless this section is commented out.

Code: [Select]

//Set-up the RF receiver
//  vw_setup(1000);                     // Bits per sec
//  vw_set_rx_pin(rxPin);               // We will be receiving on pin 2 ie the RX pin from the module connects to this pin.
//  vw_rx_start();                      // Start the receiver



Just looking through numerous threads on VirtualWire to see if there is a conflict ?

PaulS

I though you had this working. I'd go back to that version, and make one change at a time, to see what breaks the code.

bld


Quote
String message;

    for (int i = 0; i < buflen; i++) // Run through the stuff we just received
    {
      message += buf; // Append the stuff to a String
    }

What a waste of memory. A String is allocated, with 0 bytes. Then, that object is destroyed, and replaced with one that contains 1 byte. Then, that object is destroyed, and replaced with one that contains 2 bytes. Then, that object is destroyed, and replaced with one that contains 3 bytes.

This process is repeated, allocating little blocks that are hard to re-use, since they are so small.

Code: [Select]
String message(buf);
Accomplishes the same end result, without all the intermediate memory allocations.

Since you have a fair number of constant strings, and libraries that allocate blocks of memory, I'd guess that you are running out of memory.

Time to consider ditching the String call altogether. Everything that it does can be done using standard string functions, like strtok().

I have been trying this, but there are a problem. It seems to remember what the message was last time, even when the message is defined inside the loop, next time it loops around, it can still remember what it was last time.

First time I send it the message "gar-3-1" and it returns "gar-3-1", which is correct.

But when I do the following:

gar-3-1 reply from arduino is gar-3-1
gar-3-0 reply gar-3-1
gar-3-1-250 reply gar-3-1-250
gar-3-0 reply gar-3-0-250
gar-3-1 reply gar-3-1-250
gar- reply gar-3-1-250

I am running into problems, as it seems to remember what was in the message last time, and only replacing the new first of it, and then leaves the rest as it is.

Should it remember it from loop to loop? Or do I have to empty the message again? (and how to empty it)
captain-slow.dk | non contagious!

PaulS

Quote
Should it remember it from loop to loop? Or do I have to empty the message again? (and how to empty it)

"Should it". What's it?

"remember it". What is this it?

Code: [Select]
String message(buf);
Clearly, buf needs to be "empty" in order for message to be "empty".
Code: [Select]
buf[0] = '\0';
String message(buf);

bld


Quote
Should it remember it from loop to loop? Or do I have to empty the message again? (and how to empty it)

"Should it". What's it?

"remember it". What is this it?

Code: [Select]
String message(buf);
Clearly, buf needs to be "empty" in order for message to be "empty".
Code: [Select]
buf[0] = '\0';
String message(buf);


"it" being the message of course, the only thing I have been talking about.

But why would it be remembered for each time it loops?

if it is all done inside of the loop, shouldn't it then be forgotten again when it loops again? Unless "message" was defined out side of loop()
captain-slow.dk | non contagious!

PaulS

Quote
"it" being the message of course

So, you are asking:
Quote
Should the message remember the message from loop to loop? Or do I have to empty the message again? (and how to empty the message )

So, again, I have to ask are you referring to the variable message or the variable buf?

The variable message goes out of scope at the end of loop, so I would not expect message to remember it's contents from one iteration of loop to the next.

buf is also a local variable, so I would not expect buf to remember it's contents from one iteration of loop to the next.

bld


The variable message goes out of scope at the end of loop, so I would not expect message to remember it's contents from one iteration of loop to the next.

buf is also a local variable, so I would not expect buf to remember it's contents from one iteration of loop to the next.

I expected the same, but somehow String message((char *)buf); is remembered.

Code: [Select]
static String ident = "gar";    // Identification for this device

#include <VirtualWire.h>
#define rxPin 2

#define DEBUG 1 //Define to include serial communication

const int ledPin =  13;          // The number of the LED pin, LED used to indicate we got a message
long onMillis = 0;               // Will store last time LED was updated

#define startPin 3               // The first pin we connect a relay to
#define stopPin 6                // The last pin we connect a relay to

void rf_start()
{
 //Set-up the RF receiver
 vw_rx_stop();                  // Stop it in case it is already running
 vw_set_rx_pin(rxPin);          // We will be receiving on pin 2 ie the RX pin from the module connects to this pin.
 vw_setup(1000);                // Bits per sec
 vw_rx_start();                 // Start the receiver
}

void setup()
{
 
#ifdef DEBUG
 Serial.begin(9600);
#endif

 pinMode(ledPin, OUTPUT);

 //Set-up the RF receiver
 rf_start();

 for (int i = startPin; i <= stopPin; i++) // We need to set the pins that control the relays to OUTPUT
 {
#ifdef DEBUG
   Serial.print("Setting pinMode on pin: ");
   Serial.println(i);
#endif
   pinMode(i, OUTPUT);
   digitalWrite(i, LOW); // We set the pin to LOW because pulling it HIGH will turn the relay on
 }

 Serial.println("Ready to receive!");
}

void loop()
{
 uint8_t buf[VW_MAX_MESSAGE_LEN];
 uint8_t buflen = VW_MAX_MESSAGE_LEN;

 if (vw_get_message(buf, &buflen)) // Check to see if anything has been received
 {
   String message;

   for (int i = 0; i < buflen; i++) // Run through the stuff we just received
   {
     message += buf[i]; // Append the stuff to a String
   }

   //String message((char *)buf); //Store the message received

   if (message.substring(0,ident.length()) == ident) // Check if this message was for us
   {
     digitalWrite(ledPin, HIGH); // Turn led on to indicate we received something, and is going to look more at it
     onMillis = millis(); // Save when led was turned on so we remember to turn it off again later

     message = message.substring(ident.length()+1); // Remove the identifier from the message

     int startCommand = message.indexOf('-'); // Find where we split pin number from pin status

     String getPinNum = message.substring(0, startCommand); // Save a String with the pin number
     String getPinSet = message.substring(startCommand + 1, message.length()); // Save a String with the value we are going to send to the pin

     int delayCommand = message.indexOf('-', startCommand + 2); // Check if there is added a delay for the pin to be turned off again

     char tempNum[10]; //Char to hold the message before converting it to an integer

     int pinDelay = 0;

     if (delayCommand > 0)
     {
       getPinSet = message.substring(startCommand + 1, delayCommand); // Save a String with the value we are going to flash the pin

       String getPinDel = message.substring(delayCommand + 1, message.length()); // Save a String with the value we are going to delay the flash
       tempNum[getPinDel.length() + 1]; // Temp save pin value
       getPinDel.toCharArray(tempNum, 10);
       pinDelay = atoi(tempNum); // Convert char array to an integer
     }
     else
     {
       pinDelay = 0;
     }

     tempNum[getPinNum.length() + 1]; // Temp save pin number
     getPinNum.toCharArray(tempNum, 10);
     int pinNum = atoi(tempNum); // Convert char array to an integer

     tempNum[getPinSet.length() + 1]; // Temp save pin value
     getPinSet.toCharArray(tempNum, 10);
     int pinSet = atoi(tempNum); // Convert char array to an integer
     
#ifdef DEBUG
     Serial.print("Pin num: ");
     Serial.print(pinNum);
#endif

     if (pinNum != rxPin) //Make sure it won't be possible to accidently diable communication
     {
       if (pinDelay > 0)
       {
         
#ifdef DEBUG
         Serial.print(" - Cycles: ");
         Serial.print(pinSet);

         Serial.print(" - Delay: ");
         Serial.println(pinDelay);
#endif

         for (int i = 0; i < pinSet; i++)
         {
           digitalWrite(pinNum, HIGH); // Set the pin defined earlier
           delay(pinDelay);
           digitalWrite(pinNum, LOW); // Set the pin to the opposite as defined earlier
           if (i < pinSet-1) delay(pinDelay);
         }
       }
       else
       {
         
#ifdef DEBUG
         Serial.print(" - Pin status: ");
         Serial.println(pinSet);
#endif

         digitalWrite(pinNum, pinSet); // Set the pin defined earlier
       }
     }
     
#ifdef DEBUG
     else
     {
       Serial.println("WARNING: Can not change RX pin!");
     }
#endif

   }
 }

 if (millis() - onMillis > 250 && onMillis > 0) // Check if it is time to turn the led off
 {
   onMillis = 0;
   digitalWrite(ledPin, LOW);
 }
}

This gives me the expected output:
gar-3-1 reply gar-3-1
gar-3-0 reply gar-3-0
gar-3-1-250 reply gar-3-1-250
gar-3-0 reply gar-3-0
gar-3-1 reply gar-3-1
captain-slow.dk | non contagious!

bld

Where this
Code: [Select]
static String ident = "gar";    // Identification for this device

#include <VirtualWire.h>
#define rxPin 2

#define DEBUG 1 //Define to include serial communication

const int ledPin =  13;          // The number of the LED pin, LED used to indicate we got a message
long onMillis = 0;               // Will store last time LED was updated

#define startPin 3               // The first pin we connect a relay to
#define stopPin 6                // The last pin we connect a relay to

void rf_start()
{
 //Set-up the RF receiver
 vw_rx_stop();                  // Stop it in case it is already running
 vw_set_rx_pin(rxPin);          // We will be receiving on pin 2 ie the RX pin from the module connects to this pin.
 vw_setup(1000);                // Bits per sec
 vw_rx_start();                 // Start the receiver
}

void setup()
{
 
#ifdef DEBUG
 Serial.begin(9600);
#endif

 pinMode(ledPin, OUTPUT);

 //Set-up the RF receiver
 rf_start();

 for (int i = startPin; i <= stopPin; i++) // We need to set the pins that control the relays to OUTPUT
 {
#ifdef DEBUG
   Serial.print("Setting pinMode on pin: ");
   Serial.println(i);
#endif
   pinMode(i, OUTPUT);
   digitalWrite(i, LOW); // We set the pin to LOW because pulling it HIGH will turn the relay on
 }

 Serial.println("Ready to receive!");
}

void loop()
{
 uint8_t buf[VW_MAX_MESSAGE_LEN];
 uint8_t buflen = VW_MAX_MESSAGE_LEN;

 if (vw_get_message(buf, &buflen)) // Check to see if anything has been received
 {
   /*
   String message;

   for (int i = 0; i < buflen; i++) // Run through the stuff we just received
   {
     message += buf[i]; // Append the stuff to a String
   }
   */

   String message((char *)buf); //Store the message received

   if (message.substring(0,ident.length()) == ident) // Check if this message was for us
   {
     digitalWrite(ledPin, HIGH); // Turn led on to indicate we received something, and is going to look more at it
     onMillis = millis(); // Save when led was turned on so we remember to turn it off again later

     message = message.substring(ident.length()+1); // Remove the identifier from the message

     int startCommand = message.indexOf('-'); // Find where we split pin number from pin status

     String getPinNum = message.substring(0, startCommand); // Save a String with the pin number
     String getPinSet = message.substring(startCommand + 1, message.length()); // Save a String with the value we are going to send to the pin

     int delayCommand = message.indexOf('-', startCommand + 2); // Check if there is added a delay for the pin to be turned off again

     char tempNum[10]; //Char to hold the message before converting it to an integer

     int pinDelay = 0;

     if (delayCommand > 0)
     {
       getPinSet = message.substring(startCommand + 1, delayCommand); // Save a String with the value we are going to flash the pin

       String getPinDel = message.substring(delayCommand + 1, message.length()); // Save a String with the value we are going to delay the flash
       tempNum[getPinDel.length() + 1]; // Temp save pin value
       getPinDel.toCharArray(tempNum, 10);
       pinDelay = atoi(tempNum); // Convert char array to an integer
     }
     else
     {
       pinDelay = 0;
     }

     tempNum[getPinNum.length() + 1]; // Temp save pin number
     getPinNum.toCharArray(tempNum, 10);
     int pinNum = atoi(tempNum); // Convert char array to an integer

     tempNum[getPinSet.length() + 1]; // Temp save pin value
     getPinSet.toCharArray(tempNum, 10);
     int pinSet = atoi(tempNum); // Convert char array to an integer
     
#ifdef DEBUG
     Serial.print("Pin num: ");
     Serial.print(pinNum);
#endif

     if (pinNum != rxPin) //Make sure it won't be possible to accidently diable communication
     {
       if (pinDelay > 0)
       {
         
#ifdef DEBUG
         Serial.print(" - Cycles: ");
         Serial.print(pinSet);

         Serial.print(" - Delay: ");
         Serial.println(pinDelay);
#endif

         for (int i = 0; i < pinSet; i++)
         {
           digitalWrite(pinNum, HIGH); // Set the pin defined earlier
           delay(pinDelay);
           digitalWrite(pinNum, LOW); // Set the pin to the opposite as defined earlier
           if (i < pinSet-1) delay(pinDelay);
         }
       }
       else
       {
         
#ifdef DEBUG
         Serial.print(" - Pin status: ");
         Serial.println(pinSet);
#endif

         digitalWrite(pinNum, pinSet); // Set the pin defined earlier
       }
     }
     
#ifdef DEBUG
     else
     {
       Serial.println("WARNING: Can not change RX pin!");
     }
#endif

   }
 }

 if (millis() - onMillis > 250 && onMillis > 0) // Check if it is time to turn the led off
 {
   onMillis = 0;
   digitalWrite(ledPin, LOW);
 }
}

Instead give me this output:
gar-3-1 reply gar-3-1
gar-3-0 reply gar-3-0
gar-3-1-250 reply gar-3-1-250
gar-3-0 reply gar-3-0-250
gar-3-1 reply gar-3-1-250
captain-slow.dk | non contagious!

PaulS

Aha. That is because vw_get_message() is not a string function. The buffer that it returns is NOT null terminated.

Add
Code: [Select]
buf[bufLen] = '\0';
After the call to vw_get_message(), and the second code will work, too.

Go Up