using Textfinder library with Adafruit CC3000

Hi,

I'm working on a project to change some LED's based on a data on a webpage. Right now I'm able to connect to my wireless router and print the contents of the webpage to my serial monitor using a WebClient example from Adafruit. I would now like to grab my target data from the incoming stream.

I've read about char arrarys but I'm in over my head there. I was thinking that a good option would be to use the TextFinder library but I do not know how to 'pair' my CC3000 module/library to the TextFinder functions since it was written for the Ethernet library.

What would I use instead of "client" below?

 TextFinder finder( client );

Correct me if I'm wrong, but I think that my CC3000 sketch uses "www" instead of "client" for it's commands.

 Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);\

But when I use "TextFinder finder( www );" I get the following error message. Is it even possible to use the Adafruit_CC3000 library and TextFinder?

In function 'int getWaves()':
139: error: no matching function for call to 'TextFinder::TextFinder(Adafruit_CC3000_Client&)'
C:\Users\sam\Documents\Arduino\libraries\TextFinder/TextFinder.h:63: note: candidates are: TextFinder::TextFinder(Stream&, int)
C:\Users\sam\Documents\Arduino\libraries\TextFinder/TextFinder.h:43: note: TextFinder::TextFinder(const TextFinder&)

Here is my full code. Thanks for reading!

/*************************************************** 
 * This is an example for the Adafruit CC3000 Wifi Breakout & Shield
 * 
 * Designed specifically to work with the Adafruit WiFi products:
 * ----> https://www.adafruit.com/products/1469
 * 
 * Adafruit invests time and resources providing this open source code, 
 * please support Adafruit and open-source hardware by purchasing 
 * products from Adafruit!
 * 
 * Written by Limor Fried & Kevin Townsend for Adafruit Industries.  
 * BSD license, all text above must be included in any redistribution
 ****************************************************/
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include <TextFinder.h>
#include <Adafruit_NeoPixel.h> 
#define PIN 2
Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);

// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIV2); 

#define WLAN_SSID       "wifi"           
#define WLAN_PASS       "pass"
#define WLAN_SECURITY   WLAN_SEC_WPA 
#define IDLE_TIMEOUT_MS  3000      
#define WEBSITE      "feeds.feedburner.com"
#define WEBPAGE      "/surfline-rss-surf-report-south-san-diego"

uint32_t ip;

void setup(void)
{
  strip.begin();
  colorWipe(strip.Color(255, 0, 255), 50);  
  Serial.begin(115200);
}

void loop() {
  initWifi();
  deleteOldConn();
  connectWifi();
  requestDCHP();
  int wreq=getWaves();
  delay(10000);

}

// Fill the neopixels one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

//Start up cc3000 wifi chip
void initWifi(void){
  Serial.println(F("CC3000 and beyond\n")); 
  Serial.print("Free RAM: "); 
  Serial.println(getFreeRam(), DEC);
  Serial.println(F("\nInitialising the CC3000 ..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
    while(1);
  }
}

// Delete any old connection data on the module
void deleteOldConn(void){
  Serial.println(F("\nDeleting old connection profiles"));
  if (!cc3000.deleteProfiles()) {
    Serial.println(F("Failed!"));
    while(1);
  }
}

//connect to wireless network
void connectWifi(void){
  /* Attempt to connect to an access point */
  char *ssid = WLAN_SSID;             /* Max 32 chars */
  Serial.print(F("\nAttempting to connect to ")); 
  Serial.println(ssid);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }

  Serial.println(F("Connected!"));
  Serial.println(F("\n"));
}


// Wait for DHCP to complete 
void requestDCHP(){
  Serial.println(F("Requesting DHCP..."));
  while (!cc3000.checkDHCP())
  {
    delay(100); // ToDo: Insert a DHCP timeout!
  }  
  Serial.println(F("DCHP Done."));
  Serial.println(F("\n\n"));
}

// search for wave data
int getWaves(){
  uint32_t ip = 0;
  String readString = "";
  Serial.println(F("Connecting to website..."));
  while  (ip  ==  0)  {
    if  (!  cc3000.getHostByName(WEBSITE, &ip))  {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }  
  cc3000.printIPdotsRev(ip);  

  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  \
  //TextFinder finder( www ); 

  Serial.println(F("Text Return:"));
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(WEBPAGE);
    www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: ")); 
    www.fastrprint(WEBSITE); 
    www.fastrprint(F("\r\n"));
    www.fastrprint(F("\r\n"));
    www.println();
  } 
  //else {
  // Serial.println(F("Connection failed"));    
  // return;
  //}

  Serial.println(F("-------------------------------------"));

  /* Read data until either the connection is closed, or the idle timeout is reached. */
  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      Serial.print(c);
      lastRead = millis();
    }
  }
  www.close();
  Serial.println(F("-------------------------------------"));
  Serial.println(F("\n"));
}

The lovely people at Adafruit let me know that I can't use TextFinder and the CC3000. Adafruit is awesome.

TextFinder is expecting an argument of type Class Stream. Adafruit_CC3000_Client is subclassed from Class Print, not Stream. You can't pass it to TextFinder.

Adafruit is awesome.

Will they let you return their wifi board since it won't do what you need?

Oh I'm sorry, I wasn't trying to be sarcastic. I do love Adafruit! I'm certain the problem lies in my C skills and Textfinder seemed like an easy path to my end goal.

After reading a ton of your (zoomkat) and PaulS's previous posts, I think that I want to create a char array and only store the data I'm interested in to use in my sketch.

The below is some web weather code somebody posted in the past and is works with the 5100 Ethernet shield. You might adapt the way it works to do some things you want to do.

// Include description files for other libraries used (if any)
#include <SPI.h>
#include <Ethernet.h>

// Define Constants
// Max string length may have to be adjusted depending on data to be extracted
#define MAX_STRING_LEN  20

// Setup vars
char tagStr[MAX_STRING_LEN] = "";
char dataStr[MAX_STRING_LEN] = "";
char tmpStr[MAX_STRING_LEN] = "";
char endTag[3] = {'<', '/', '\0'};
int len;

// Flags to differentiate XML tags from document elements (ie. data)
boolean tagFlag = false;
boolean dataFlag = false;

// Ethernet vars
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 102 };
byte server[] = { 140, 90, 113, 200 }; // www.weather.gov

// Start ethernet client
EthernetClient client;

void setup()
{
  Serial.begin(9600);
  Serial.println("Starting WebWx");
  Serial.println("connecting...");
  Ethernet.begin(mac, ip);
  delay(1000);

  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println("GET /xml/current_obs/KRDU.xml HTTP/1.0");    
    client.println();
    delay(2000);
  } else {
    Serial.println("connection failed");
  }  
}

void loop() {

  // Read serial data in from web:
  while (client.available()) {
    serialEvent();
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("Disconnected");
    Serial.println("==================================");
    Serial.println("");
    client.stop();

    // Time until next update
    //Serial.println("Waiting");
    for (int t = 1; t <= 15; t++) {
      delay(60000); // 1 minute
    }

    if (client.connect(server, 80)) {
      //Serial.println("Reconnected");
      client.println("GET /xml/current_obs/KRDU.xml HTTP/1.0");    
      client.println();
      delay(2000);
    } else {
      Serial.println("Reconnect failed");
    }      
  }
}

// Process each char from web
void serialEvent() {

   // Read a char
	char inChar = client.read();
   //Serial.print(".");
  
   if (inChar == '<') {
      addChar(inChar, tmpStr);
      tagFlag = true;
      dataFlag = false;

   } else if (inChar == '>') {
      addChar(inChar, tmpStr);

      if (tagFlag) {      
         strncpy(tagStr, tmpStr, strlen(tmpStr)+1);
      }

      // Clear tmp
      clearStr(tmpStr);

      tagFlag = false;
      dataFlag = true;      
      
   } else if (inChar != 10) {
      if (tagFlag) {
         // Add tag char to string
         addChar(inChar, tmpStr);

         // Check for </XML> end tag, ignore it
         if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) {
            clearStr(tmpStr);
            tagFlag = false;
            dataFlag = false;
         }
      }
      
      if (dataFlag) {
         // Add data char to string
         addChar(inChar, dataStr);
      }
   }  
  
   // If a LF, process the line
   if (inChar == 10 ) {

/*
      Serial.print("tagStr: ");
      Serial.println(tagStr);
      Serial.print("dataStr: ");
      Serial.println(dataStr);
*/

      // Find specific tags and print data
      if (matchTag("<temp_f>")) {
	      Serial.print("Temp: ");
         Serial.print(dataStr);
      }
      if (matchTag("<relative_humidity>")) {
	      Serial.print(", Humidity: ");
         Serial.print(dataStr);
      }
      if (matchTag("<pressure_in>")) {
	      Serial.print(", Pressure: ");
         Serial.print(dataStr);
         Serial.println("");
      }

      // Clear all strings
      clearStr(tmpStr);
      clearStr(tagStr);
      clearStr(dataStr);

      // Clear Flags
      tagFlag = false;
      dataFlag = false;
   }
}

/////////////////////
// Other Functions //
/////////////////////

// Function to clear a string
void clearStr (char* str) {
   int len = strlen(str);
   for (int c = 0; c < len; c++) {
      str[c] = 0;
   }
}

//Function to add a char to a string and check its length
void addChar (char ch, char* str) {
   char *tagMsg  = "<TRUNCATED_TAG>";
   char *dataMsg = "-TRUNCATED_DATA-";

   // Check the max size of the string to make sure it doesn't grow too
   // big.  If string is beyond MAX_STRING_LEN assume it is unimportant
   // and replace it with a warning message.
   if (strlen(str) > MAX_STRING_LEN - 2) {
      if (tagFlag) {
         clearStr(tagStr);
         strcpy(tagStr,tagMsg);
      }
      if (dataFlag) {
         clearStr(dataStr);
         strcpy(dataStr,dataMsg);
      }

      // Clear the temp buffer and flags to stop current processing
      clearStr(tmpStr);
      tagFlag = false;
      dataFlag = false;

   } else {
      // Add char to string
      str[strlen(str)] = ch;
   }
}

// Function to check the current tag for a specific string
boolean matchTag (char* searchTag) {
   if ( strcmp(tagStr, searchTag) == 0 ) {
      return true;
   } else {
      return false;
   }
}

Thank you, zoomkat! I will give this a try tonight.

I was able to overcome the problem using string functions. I created a buffer by adding each character to the previous and then scanning the buffer after closing the connection. I was looking to extract specific fields and quit the scan after the last field. Fields are delimited by a quote mark.

The Web stream returned is a JSON stream. You can get a free key from the site so I changed that line in the page definition.

Most of the code is from the Adafruit Web Client example.

CC3000_WebClient_Weather_Json ForumPost.txt (10.8 KB)

An additional note to anyone reading this post.

The code fails on an UNO R3 as buff does not get filled with the entire stream. I have been running my tests on a MEGA2560. Further testing on my part needs to be done to see if I can make the code work with a static buffer. I think I may have run out of memory. The code uploades at 27,236.

Hi!

I've the CC3000 wifi chip and i need to print a webpage into a local network, but I'm really getting mad, because i've been researching it for a couple of days and testing sketches and i found nothing.

What i need to do is print a webpage and modify ( mostly boolean and integer) variables from a webpage (it's not needed to be the same website)

I've read this post and i thnk is not the same stuff, but maybe you can help me out.

thanks

but maybe you can help me out.

Without seeing your code, and the input, and knowing how that it to become the output, the only way we can help you out is out the door. I'm guessing that's not the kind of help you want.