Xbee to Arduino Serial Response

My Mum is not so able anymore so I installed a watering system for her garden using solenoids running from an Arduino UNO R3 and xbee series 2 on a sparkfun xbee shield. The xbee was sending moisture levels and waterings via xig on a connectport x2 to a online database.

Everything was working great until the moisture sensors gradually corroded making the programs moisture settings incorrect. I'm currently replacing the corroded sensors with better quality ones but I figured I'd also add a control for the moisture settings that Mum can access online. I have a webpage that grabs her moisture setting percent and sends it back to the connectport.

The problem I'm finding is that I can't seem to get the correct serial data back to the arduino. I know it's currently set at 65 and I've been using a simple sketch to test the serial response but instead of 65 I'm getting what seems like random numbers such as 48, 51, 49, 105, 112, 111. I'm new to arduino and have spent the last week trouble-shooting this seemingly simple problem but to no avail so I'm hoping someone can help point me in the right direction? My test code is:-

int moistureSetting = 70;
void setup() {

Serial.begin(57600);
delay(2000);

}
void loop() {
    Serial.print("http://www.tempus4.com.au/CazzasGarden/settingmoist/frontyardmoisttext.txt");
    delay(10);
    while(Serial.available() > 0)
    {
      int moistureSetting = Serial.read();  
      Serial.print("http://data.sparkfun.com/input/4JJrLvy7KbiLLy1x19Eq?private_key=b55KJlmM7VU55q4p4je2&moisture=");
      Serial.println(moistureSetting);
    }
  delay(5000);
}

What is the Arduino sending serial data to? I can't see the Serial Monitor caring about the "URL".

In other words, what is sending serial data to the Arduino? I suspect that whatever it is is sending ASCII data. Have a peek at http://www.asciitable.com/, and see if the numbers you are seeing provide a clue.

Thanks Paul,

The way it’s working is that the Arduino sends the “URL” via the xbee to the connectport which has a python application called “XIG” that detects URL’s in serial data and sends them on to their web address. This has been working fine so far to log garden moisture data onto a web database. The XIG application also receives the result of the webpage (which is simply a number between 0 and 100 with no html) and passes that onto the xbee but I can’t seem to get this part to work.

Your suspicion that the data is ASCII characters is spot on. I’ve since monitored the serial data and have translated some of the copious info here (“0 forbidden: invalid key 65 Xig-Error: unable to perform HTTP request…”). The rest is either a response from the database’s website with mostly errors or more commonly a response from the XIG which comes in the form of XIG help info. I think the XIG help is a automatic response if the XIG receives something it’s not expecting.

I’ve now changed the code so that the “int” is a “char” in the code at the bottom of this post. I also changed the webpage it opens first from a txt file to a php file that outputs the number 65. I also added an “if” to only accept numbers but that didn’t seem to work as here’s an example of the serial data:-

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php
http://data.sparkfun.com/input/4JJrLvy7KbiLLy1x19Eq?private_key=b55KJlmM7VU55q4p4je2&moisture=.
p
u
s
h
http://data.sparkfun.com/input/4JJrLvy7KbiLLy1x19Eq?private_key=b55KJlmM7VU55q4p4je2&moisture=(
http://data.sparkfun.com/input/4JJrLvy7KbiLLy1x19Eq?private_key=b55KJlmM7VU55q4p4je2&moisture=[
http://data.sparkfun.com/input/4JJrLvy7KbiLLy1x19Eq?private_key=b55KJlmM7VU55q4p4je2&moisture=
s
e
t
http://data.sparkfun.com/input/4JJrLvy7KbiLLy1x19Eq?private_key=b55KJlmM7VU55q4p4je2&moisture=C
o
o
k
i
e

char moistureSetting = 70;
void setup() {

Serial.begin(57600);
delay(2000);

}
void loop() {
    Serial.println("http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php");
    delay(10);
    while(Serial.available() > 0)
    {
      char moistureSetting = Serial.read();  
      if (moistureSetting >= 0 && moistureSetting <= 100)
        Serial.print("http://data.sparkfun.com/input/4JJrLvy7KbiLLy1x19Eq?private_key=b55KJlmM7VU55q4p4je2&moisture=");
        Serial.println(moistureSetting);
    }
  delay(5000);
}

There are still at least two problems with your code. First:

    Serial.println("http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php");
    delay(10);
    while(Serial.available() > 0)

In my wildest dreams, I can not imagine that 10 milliseconds is enough time to shuffle out all that data AND have the server send back a response.

      char moistureSetting = Serial.read();  
      if (moistureSetting >= 0 && moistureSetting <= 100)

I seriously doubt that the server responds with a BINARY value between 0 and 100. Instead, I suspect that the server responds with a value that is between 0 and 100 AS A STRING OF CHARACTERS. That is, if the value is 65, it is sending ‘6’ and ‘5’. It is even more likely that it is sending something more like ‘6’, ‘5’, ‘’, ‘’. You need to determine what the delimiter(s) is/are that mark the end of the string of data, and read and store data until the end of packet marker arrives, appending a NULL to the array after each character is stored, and then call atoi() on the stored string when the end of packet marker arrives.

For now, move the first Serial.println() statement to setup(). Then, in loop(), simply read any data that arrives, and print the value:

void loop()
{
   if(Serial.available() > 0)
   {
      char c = Serial.read();
      Serial.print(c, HEX);
      Serial.print(' ');
   }
}

Show us the output that this produces.

Thanks Paul,

I’m getting a little excited now… I just ran your suggested code and the serial monitor result was:-

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php
36 35

That’s HEX for characters 6 and 5.

One of the issues that I can see is that you are using the hardware serial pins to talk to the Serial Monitor AND to talk to the python application. I can see that one or the other is going to get confused.

I’m a bit surprised that there is nothing after the 2 digit response.

ThatsnotaverygoodideaforobviousreasonsDoyouhaveanycontroloverwhatreturnstheresponse

It's just a php file that is currently generating the number 65... or will be whatever number between 0 and 100 that my Mum chooses. I can easily add something else after this number if it's needed?

I added the "@" after the numbers on the page so now I get the following:- http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php 36 35 40

I added the “@” after the numbers on the page so now I get the following

Great. So, now add:

char stuff[10];
byte index = 0;

before setup(), and make loop look like:

void loop()
{
   if(Serial.available() > 0)
   {
      char c = Serial.read();
      if(c != '@')
      {
         if(index < 9)
         {
            stuff[index++] = c;
            stuff[index] = '\0';
         }
      }
      else
      {
         Serial.print("The value is: ");
         Serial.println(atoi(stuff));
      }
   }
}

That worked! Thanks Paul! I can’t say I fully understand the code but I think I’m getting there.

Now, I have to consider that the program running the watering checks the moisture every 15 minutes and unless I’m mistaken I have to move the “Serial.print(“http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php”);” into the loop?
I just tried it and the results start off ok but then things get messed up. Below is the serial output and I’ve posted the new code at the bottom too.

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php
The value is: 65

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php
The value is: 6565

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php
The value is: 1205

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php
The value is: -10507

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php

http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php
The value is: 26008

The value continues to come out as 26008 from here out? It’s odd that it takes 3 loops before I get a value. I even extended the delay to 10 seconds and no change to the results.

char c = 0;
char stuff[10];
byte index = 0;

void setup() {

Serial.begin(57600);
delay(1000);
//Serial.println(' ');
//Serial.println("http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php");

}
void loop() {

    Serial.println(' ');
    Serial.println("http://www.tempus4.com.au/CazzasGarden/settingmoist/3.php");
    delay(3000);
{
   if(Serial.available() > 0)
   {
      char c = Serial.read();
      if(c != '@')
      {
         if(index < 9)
         {
            stuff[index++] = c;
            stuff[index] = '\0';
         }
      }
      else
      {
         Serial.print("The value is: ");
         Serial.println(atoi(stuff));
      }
   }
}

My code had no expectation that you were going to add Serial.print() statements in loop() to send "URL" info again.

If you are going to do that, you need to make some changes:

      else
      {
         Serial.print("The value is: ");
         Serial.println(atoi(stuff));

          index = 0;
          stuff[index] = '\0';
      }

I see, I did try resetting the index but not the stuff[index]... Thanks again!

The value comes out correct now but it still loops 3 times before the value prints... no mater what delay I give it before checking the Serial.available. I can't see why this would occur?

The value comes out correct now but it still loops 3 times before the value prints... no mater what delay I give it before checking the Serial.available. I can't see why this would occur?

Let's think about this. You send a request. You (eventually) get a response. When would be a good time to send another request?

It's just odd that with your original code when the URL is sent from in the "setup" it works first time it runs but when it's within the loop with the same conditions it takes 3 times before it outputs and it's consistently 3 times no matter the delay I give it.

I'm sorry if I'm overlooking the painfully obvious here (especially when you've been so much help) but I think the answer to your question would be to send the next request straight after?

Once again Paul, thank-you so much! I've had a week of frustrations and now the accumulated weight on my shoulders has lifted thanks to your help. Cheers from Australia... my Mum will be especially pleased!