replacing a while loop with something else?

ok so i have made a sketch that search for strings and keywords within a website but its currently in a while loop till it finds what its looking for,my question is how can i fix this up so that it doesnt tie up the sketch cause of the while loop but at the same time keep it running in the background…

i wanted to be able to run other codes while this is searching for the keyword… ? any help would be great…

here is my sketch:

//Some Libraries needed to perform the code properly
#include <SPI.h> //For internetconnection
#include <Ethernet.h> //For internetconnection
#include <TextFinder.h> //Needed for finding weatherrating
int firsttime = 1;
int minTemp = 0;

//used for internetconnection
EthernetClient client;
TextFinder finder( client);



char cond[36];

void setup(){
   Serial.begin(115200);  }
   
void loop(){

getrating();
client.stop(); 
delay(2000);
firsttime=1;
minTemp=0;
}  
   
int getrating(){
while(minTemp==0){
  
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char serverName[] = "www.meteovista.co.uk";
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,115);
  
  if(firsttime==1){
    // start the internet connection
    
  Serial.print("connecting....");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // if DHCP fails to auto assign an IP address then
    // try to set Static IP address for Ethernet shield
    Ethernet.begin(mac, ip);
  }
  delay(1000);
  
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    // Making HTTP request
    client.println("GET /North-America/United-States/San-Diego/4952208 HTTP/1.1");
    client.println("Host: www.meteovista.co.uk");
    client.println();
    client.println("Searching xml for data...");
    client.println();
  } 
  else {
    // no response from server?
    Serial.println("connection failed");
  }
  
  firsttime = 0;
 }
 
  // read weathermark from page
  if (client.available()) {
    
    if(finder.find("Minimum temperature") )
     {      
        minTemp = finder.getValue();
             
        Serial.print("The Minimum temperature is ");  // Send the weatherrating via the Serial port to your computer
        Serial.println(minTemp);
      }
      
    if(finder.find("Maximum temperature") )
     {      
        int maxTemp = finder.getValue();
             
        Serial.print("The Maximum temperature is ");  // Send the weatherrating via the Serial port to your computer
        Serial.println(maxTemp);
      }
      
        if(finder.find("<tr class=\"row_weathernumbers\">") )
         {  
       Serial.println("Found string row_weathernumbers!");    
        if (finder.find("title="))
          {
            finder.getString("\"", ".", cond, 36);
            //Serial.print("Forecast Condition: ");
            Serial.println(cond);
            Serial.println();
          } else { Serial.println("Forecast Condition: Failed to connect!");}
         }
  }

  // Stop if de server ended the connection
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting...");
    client.stop();
    }
  }
}

Look at the 'sticky' post, "Doing several things at a time." posted by Robin2, near the top of the Project Guidance forum list.

Millis() , look at Robin2 post, its very useful

only issue is that the the while loop is running the ethernet check and its looping the thing over and over till it finds what it needs and for that reason i cant seem to get it to work right...

This does not seem to be a millis() problem, but I suspect the solution will be similar.

I can't figure what the other functions called from loop() are for. For example, if you stop using WHILE it probably does not make any sense to use client.stop() or, indeed, delay(2000) during the period that you should be checking the web.

I think it would be a good idea to write down the steps that you want to happen - one step on each line - so that you (and we) have a clear picture of the process you want to implement.

And, while it is unlikely to be part of the problem, why is byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; within any sort of loop. And probably also unwise to publish your MAC address.

...R

The only while I find in your code is based on temperature being equal to zero. I can't see any logical reason why you would use WHILE here, why not just IF

bryanmc1988: ok so i have made a sketch that search for strings and keywords within a website but its currently in a while loop till it finds what its looking for,my question is how can i fix this up so that it doesnt tie up the sketch cause of the while loop but at the same time keep it running in the background...

i wanted to be able to run other codes while this is searching for the keyword.... ? any help would be great...

You can replace a huge amount of blocking/slowing loops by using state variables, indexes and loop().

You know like how a for-next loop controls an index? So with your own index variable you can use loop() to drive the index with --- first thing is to break the do-everything start to end code approach and think of real time, a tiny wheel at high rpm will do a lot of work. When every task eligible gets a chance to run a few lines of code at a rate of 10,000 or more per second then your tasks should fly.

So if you have a process state with an array of pins to check, you use an index to check pin[0] and then increment the index and exit without changing state. Next time through loop it does the next pin and next until it gets to the end of the array and then ... it changes state and exits, letting other tasks run. Next time that function runs it does whatever the next state handles, which may include waiting without blocking. State machines and loop() can allow you to write simpler task code with fewer indents.

@Ken and @GoForSmoke - I agree with you. But the problem (as I see it) is that if the WHILE is removed from the existing code it will runs smack into other problems - hence my comments in Reply #4

...R

well this is what happens when i remove or commented out the while loop and some other items within the code…

#include <UTFT.h>  // used to interface with the TFT display
#include <UTouch.h>  // used to interface with the touch controller on the TFT display
#include <avr/pgmspace.h>
#include <tinyFAT.h> // used to acess the SD card
#include <UTFT_tinyFAT.h>  // used to read .raw images from the SD card
#include <SD.h>    //Used to check for SD card
#include <SPI.h>
#include <Ethernet.h>
#include <TextFinder.h>



//LCD TOUCH PANEL and ITDB02 MEGA SHIELD v1.1
//(Mega Shield utilizes pins 5V, 3V3, GND, 2-6, 20-41, & (50-53 for SD Card))
UTFT myGLCD(SSD1289,38,39,40,41);      //Uncomment this line for the SSD1289 TFT Screen
UTouch myTouch (6,5,4,3,2);      //Pins Used for the Touch screen
UTFT_tinyFAT myFiles(&myGLCD);  // start up an instance to read images from the SD card


EthernetClient client;
TextFinder finder( client);

//Declare which fonts to be utilized
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];


#define LARGE true
#define SMALL false


//int firsttime = 1;
//int minTemp = 0;
char cond[36];

void setFont(boolean font, byte cr, byte cg, byte cb, byte br, byte bg, byte bb)
{
  myGLCD.setBackColor(br, bg, bb);               //font background black
  myGLCD.setColor(cr, cg, cb);                   //font color white
  if (font==LARGE)
    myGLCD.setFont(BigFont);                     //font size LARGE
  else if (font==SMALL)
    myGLCD.setFont(SmallFont);
}

int getrating(){
//while(minTemp==0){
  
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char serverName[] = "www.meteovista.co.uk";
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,115);
  
  //if(firsttime==1){
    // start the internet connection
    
  Serial.print("connecting....");
  //Ethernet.begin(mac, ip);
  
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // if DHCP fails to auto assign an IP address then
    // try to set Static IP address for Ethernet shield
    Ethernet.begin(mac, ip);
  }
  delay(1000);
  
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    // Making HTTP request
    client.println("GET /North-America/United-States/San-Diego/4952208 HTTP/1.1");
    client.println("Host: www.meteovista.co.uk");
    client.println();
    
    Serial.print("My IP address: ");
    for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    if (thisByte<3){Serial.print(".");}
    }
    
    Serial.println();
    Serial.println();
    Serial.println("Searching xml for data...");
  } 
  else {
    // no response from server?
    Serial.println("connection failed");
  }
  
  //firsttime = 0;
 //}
 
  // read weathermark from page
  if (client.available()) {
    
    if(finder.find("Minimum temperature") )
     {      
        minTemp = finder.getValue();
             
        Serial.print("The Minimum temperature is ");  // Send the weatherrating via the Serial port to your computer
        Serial.println(minTemp);
      }
      
    if(finder.find("Maximum temperature") )
     {      
        int maxTemp = finder.getValue();
             
        Serial.print("The Maximum temperature is ");  // Send the weatherrating via the Serial port to your computer
        Serial.println(maxTemp);
      }
      
        if(finder.find("<tr class=\"row_weathernumbers\">") )
         {  
       Serial.println("Found string row_weathernumbers!");    
        if (finder.find("title="))
          {
            finder.getString("\"", ".", cond, 36);
            //Serial.print("Forecast Condition: ");
            Serial.println(cond);
            Serial.println();
          } else { Serial.println("Forecast Condition: Failed to connect!");}
         }
  }

  // Stop if de server ended the connection
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting...");
    client.stop();
    }
  //}
}


void setup() {
  Serial.begin(115200);
  SD.begin();
  //Serial.println("FF Weather Station");
  //Serial.println("connecting...");
  myGLCD.InitLCD(LANDSCAPE);
  myGLCD.clrScr();
  
  myTouch.InitTouch(LANDSCAPE);
  myTouch.setPrecision(PREC_MEDIUM);
  
  file.setSSpin(53);                  // init SD card
  file.initFAT(SPISPEED_VERYHIGH);
}

void loop()
{
  getrating();
  //client.stop(); 
  delay(2000);
  //firsttime=1;
  //minTemp=0;
}

and here is a ss of the serial print i am getting…

as you can see it seems as if it doesnt give enough time for the code to search for the keyword in the website.

How could it possibly work when you have commented out the line that opens the connection ...

...R

Robin2: @Ken and @GoForSmoke - I agree with you. But the problem (as I see it) is that if the WHILE is removed from the existing code it will runs smack into other problems - hence my comments in Reply #4

...R

Handle the condition with an if and a state value if need be. You don't have to process an entire list per execution of loop(), that can block other tasks.

Robin2: How could it possibly work when you have commented out the line that opens the connection ...

...R

i dont think i did...? which line did i comment out for the connection?

Did you examine your code carefully?

This line

 //Ethernet.begin( mac, ip);

...R

that was to try using it a static up address... If u look right below that u can see that it will try to connect through DHCP first and if that fails, it will try to connect using the static ip (same lane that was commented out)

has that commented lane before to see if I can just connect straight with the static up but it never worked... Always had to connect using dhcp first then if it fails then use the satic ip

bryanmc1988: that was to try using it a static up address... If u look right below that u can see that it will try to connect through DHCP

Apologies. I will retire from the battle.

...R

lol was there a battle ? if so i missed it xD just need help fixing the issue not a battle =P

P.S. still can get it to work without delaying other things running ....

bryanmc1988: lol was there a battle ?

I thought, originally, it was a simple matter of an inappropriate WHILE. But I don't know enough about ethernet stuff on an Arduino to be of much use.

...R

its ok, hope someone else can put more light to this.... as it seems that the finder.find() needs time to find the keyword but how can i replace the while loop to something else that will allow the finder.find to keep searching and not delay the whole arduino code...

any one with any help would be great...

bryanmc1988: something else that will allow the finder.find

From a brief read of the Playground page it looks like finder.find() is a blocking function that should wait until it has checked all the stream of data. If it is not finding something it seems like it is not there or the stream is empty.

If that is the case you need to do whatever is necessary to get more data from the web. Maybe when you were using WHILE it was making repeated reads that you were not aware of.

If this was my project I would write a very short program that just gets data from the web so that I could learn all about that process.

...R

i tryed but cant seem to get it to work without the loop… here is my edit code… see if u can play around with the while and see if u can get it to work… it would really help me out a lot

//Some Libraries needed to perform the code properly
#include <SPI.h> //For internetconnection
#include <Ethernet.h> //For internetconnection
#include <TextFinder.h> //Needed for finding weatherrating
int humidity = 0;

//used for internetconnection
EthernetClient client;
TextFinder finder( client);



char cond[36];

void setup(){
   Serial.begin(115200);  }
   
void loop(){

getrating();
client.stop(); 
delay(2000);
humidity=0;
}  
   
int getrating(){
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
char serverName[] = "forecast.weather.gov";
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192,168,1,115);
  
  
    // start the internet connection
  Serial.print("connecting....");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // if DHCP fails to auto assign an IP address then
    // try to set Static IP address for Ethernet shield
    Ethernet.begin(mac, ip);
  }
  delay(1000);
  
  if (client.connect(serverName, 80)) {
    Serial.println("connected");
    // Making HTTP request
    client.println("GET /MapClick.php?lat=32.7555&lon=-117.07&unit=0&lg=english&FcstType=dwml HTTP/1.1");
    client.println("Host: forecast.weather.gov");
    client.println();
    Serial.println("Searching xml for data...");
    Serial.println();
  } 
  else {
    // no response from server?
    Serial.println("connection failed");
  }
 
 
  while(humidity==0){
  // read weathermark from page
  if (client.available()) {
    
    if(finder.find("apparent") )
     {      
       if (finder.find("value") )
         {
            float currentTempF = finder.getValue();
                 
            Serial.print("TempF: ");  //Prints Current Temp in *F
            Serial.print(currentTempF, 1);
            Serial.println("*F");
            
            Serial.print("TempC: ");  //Prints Current Temp in *C
            Serial.print((currentTempF-32.05) * 0.5555555555555556, 1);
            Serial.println("*C");
         }
     }
      
    if(finder.find("relative") )
     {      
       if (finder.find("value") )
         {
            humidity = finder.getValue();
                 
            Serial.print("humidity: ");  //Print humidity %
            Serial.print(humidity);
            Serial.println("%");
            Serial.println();
            Serial.println();
         }
     }
  }

  // Stop if de server ended the connection
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting...");
    client.stop();
    }
  }
}