setURL string problem

I am trying to make my wishield do both push and pull of the data, but I got some issues with making the push dynamic. (see further down why)

#include <WString.h>
#include <WiServer.h>
#define WIRELESS_MODE_INFRA      1
#define WIRELESS_MODE_ADHOC      2

// Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = {10,0,0,15};      // IP address of WiShield
unsigned char gateway_ip[] = {192,168,1,1};      // router or gateway IP address
unsigned char subnet_mask[] = {255,255,255,0};      // subnet mask for the local network
const prog_char ssid[] PROGMEM = {"dd-wrt"};            // max 32 bytes

unsigned char security_type = 3;      // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2

// WPA/WPA2 passphrase
const prog_char security_passphrase[] PROGMEM = {"xxxxxxxxxxxxxxxxxxxxxx"};      // max 64 characters

// WEP 128-bit keys
// sample HEX keys
prog_uchar wep_keys[] PROGMEM = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,      // Key 0
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,      // Key 1
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,      // Key 2
                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00      // Key 3
                        };

// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;

unsigned char ssid_len;
unsigned char security_passphrase_len;
// End of wireless configuration parameters ----------------------------------------

// This is our page serving function that generates web pages
boolean sendMyPage(char* URL)
{
    if (strcmp(URL, "/") == 0)
    {
        // Use WiServer's print and println functions to write out the page content
          WiServer.print(analogRead(0));
          WiServer.print("|");
          WiServer.print(analogRead(1));
          WiServer.print("|");
          WiServer.print(analogRead(2));
          WiServer.print("|");
          WiServer.print(analogRead(3));
          WiServer.print("|");
          WiServer.print(millivolts(analogRead(4))); //Light sensor
          WiServer.print("|");
          WiServer.print(Thermister(analogRead(5))); //Converting into Celcius before printing
        return true;
    }
    return false;
}

float millivolts(float val)
{
   return (val / 204.0)*1000.0; //*1000 to convert it to millivolts
}

double Thermister(int RawADC)
{
  double Temp;
  Temp = log(((10240000/RawADC) - 10000));
  Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
  Temp = Temp - 273.15;            // Convert Kelvin to Celcius
  return Temp;
}

long unsigned int lcdUpd;





unsigned long timeDebounce = 10000;
unsigned long inputDebounce = 0;


// Function that prints data from the server
void printData(char* data, int len)
{
  // Print the data returned by the server
  // Note that the data is not null-terminated, may be broken up into smaller packets, and
  // includes the HTTP header.
  
  Serial.print(data);

  //while (len-- > 0)
  //{
    //Serial.print(*(data++));
  //}
  //delay(100);
}


//IP of my NAS
uint8 ip[] = {10,0,0,117};


//Define the request
GETrequest pullServer(ip, 80, "10.0.0.117", "");




void setup()
{
  Serial.begin(9600);

  Serial.print("$CLEAR\r\n");
  Serial.print("$GO 1 1\r\n");
  Serial.print("$PRINT mV       Temp\r\n");
  
  pullServer.setReturnFunc(printData);
  // Initialize WiServer and have it use the sendMyPage function to serve pages
  WiServer.init(sendMyPage);
}

void loop()
{
  // Run WiServer
  WiServer.server_task();
   
  if (millis() - inputDebounce >= timeDebounce) //One minute debounce
  {
    inputDebounce = millis();

Here it will do the pushing of the data, but if I do

String newURL = "";
    newURL.append("/arduino/logging/incomming.php?analog=");
    newURL.append(analogRead(0));
    newURL.append("|");
    newURL.append(analogRead(1));
    newURL.append("|");
    newURL.append(analogRead(2));
    newURL.append("|");
    newURL.append(analogRead(3));
    newURL.append("|");
    newURL.append(analogRead(4));
    newURL.append("|");
    newURL.append(analogRead(5));
        
    Serial.println(newURL);
    
  
    pullServer.setURL(newURL);
    pullServer.submit();

It won’t work, but if I copy the url from the Serial.println(newURL); and do like this

pullServer.setURL("/arduino/logging/incomming.php?analog=367|455|485|544|77|493");
    pullServer.submit();

It work as expected, what can the problem here be?

  }

  if ((millis() - lcdUpd) >= 500 && 1 == 2)
  {
    lcdUpd = millis();
    Serial.print("$GO 2 1\r\n");
    Serial.print("$PRINT ");
    Serial.print(millivolts(analogRead(4)));
    Serial.print(" \r\n");
    Serial.print("$GO 2 10\r\n");
    Serial.print("$PRINT ");
    Serial.print(Thermister(analogRead(5)));
    Serial.print("C \r\n");
    Serial.print("$GO 3 1\r\n");
  } 
}

As a newcomer to Arduino, I haven't had any requirement or inclination to inspect the String library.

However, I come here to learn.

So...

After downloading and installing the library and confirming your problem with the append method, I looked at the code in the library and was surprised to find various major bugs.

For example: The append() method calls the "+=" operator which totally misbehaves when trying to increase the length of the string.

A possible fix for this particular operator (+= working on a char *) might go something like this:

const String & String::operator+=( const char* bytes) {
  if(bytes == NULL) {
    bytes = "";
  }
  _length += strlen(bytes);
  if (_length > _capacity)
  {
    char *tmp = (char *)realloc(_array, _length+1);
    // We would like to throw an exception if the allocation failed,
    // but since that's not possible with Arduino, I'll just return
    // the original (unchanged) string.
    //
    if (tmp == NULL) {
        _length -= strlen(bytes);
        return *this;
    }
    _capacity = _length;
    _array = tmp;
  }
  strcat(_array, bytes);

  return *this;
}

I haven't tested very much (other than verifying that your stuff comes out OK), and I wouldn't suggest using it just yet.

Also...

There are a number of other errors in the library, and I wouldn't consider it safe. Not by a long shot.

Regards,

Dave

Serial.print("$GO 2 1\r\n");

Did you test lines like above to see if the \r\n are doing what you expect?

All the serial stuff is working… it is only the part with the pullServer.setURL(""); and pullServer.submit(); there are problems with

Everything works when it paste the url in manually, but doesn’t when i put newURL in

Working

pullServer.setURL("/arduino/logging/incomming.php?analog=367|455|485|544|77|493");
pullServer.submit();

Not working

String newURL = "";
newURL.append("/arduino/logging/incomming.php?analog=");
newURL.append(analogRead(0));
newURL.append("|");
newURL.append(analogRead(1));
newURL.append("|");
newURL.append(analogRead(2));
newURL.append("|");
newURL.append(analogRead(3));
newURL.append("|");
newURL.append(analogRead(4));
newURL.append("|");
newURL.append(analogRead(5));
        
Serial.println(newURL); //Debug to see if the url is as it should be
    
  
pullServer.setURL(newURL);
pullServer.submit();

Serial monitor

arduino/logging/incomming.php?analog=367|455|485|544|77|493

400 Bad Request

Bad Request

Your browser sent a request that this server could not understand.


Apache Server at 10.0.0.117 Port 80

I tried (really tried) to tell you exactly why the String append stuff doesn't work. There is a bug in the library. (Several bugs, actually.)

Sorry for wasting the bandwidth.

If you want to try it without changing the library (or waiting for some fixed release) you can declare a string longer than you will ever need (which kind of defeats one of the main purposes of the library)

Maybe something real kludgy (and just plain butt-ugly) like

    String newURL(150); // Extra long string
    newURL.append("/arduino/logging/incomming.php?analog=");
    newURL.append(analogRead(0));
.
.
.

Regards,

Dave

So are there other ways to do it instead? I also tried using sprintf, but for some reason my millis() goes negative when I use it. And first time it then fires and uses the sprintf it freezes and just blinks with the TX led, and is unable to reset it. Only way to get it working again, is to be prepared with the sketch, then plug the arduino in, and hit upload before it starts running...

Update: Just tried your suggestion, doesn't work either, same problem as before.

What does Serial.println(newURL) show you?

Regards,

Dave

What does Serial.println(newURL) show you?

/arduino/logging/incomming.php?analog=367|455|485|544|77|493

Values changing of curse, but if I take that link and put in my browser, it does exactly what it should do.

arduino/logging/incomming.php?analog=367|455|485|544|77|493

Have you checked the http specifications as to what you are trying to send? You are sending a query_string which may have finite limit as to length (post methods are probably better for big stuff). Most important, certain characters cannot be sent in a query_string. Try using "-" as a delimiter instead of "|". In servo control code I send I substitute "-" for "#" in the string as the "#" cannot be sent. I parce the code when received to remove the "-" and reinsert the "#".

As I already said... twice... pullServer.setURL("/arduino/logging/incomming.php?analog=367|455|485|544|77|493"); works just fine, and I have tried even longer, but the problem is that when I put it in manually (no changing values), it does what it should. And when it builds the url itself, and updates gets the new values in, it doesn't work. And I also tried changing the | to something else.. had , - and even tried a letter (wont ever be anything else than numbers in anyways), nothing works, only manually putting the url in.

Perhaps you have character/number issues. When you collect the analog values, do you convert the interger values to a character string to be sent? What you see and what is being sent may be two different things. For test purposes, try assigning string number values to the analog variables and sending them instead of the interger value being supplied.