3

I have a CC3000 wifi module from adafruit that is working OK. Now, I am trying to use it together with an external service, which code requires me to pass a Client (from Arduino SDK) reference, but the Adafruit_CC3000_Client does not inherit from Client nor WifiClient.

I am looking for an appropiate wrapper, but unable to find one. Does anyone know about such wrapper?

  • write it yourself, extends the Client class and override its method to call CC3000 method :) – Lesto Mar 31 '14 at 12:59
  • Yes, as I didnt get any answers, I have started to do so, but it is a little tricky, I will post the answer when I am able to get it working properly. – drodri Apr 1 '14 at 17:34
5

As I didn't get any answer, and further search for an existing solution failed, I decided to roll my own. The class header is very straightforward, I decided to go for single inheritance and composition of Adafruit_CC3000_Client:

class CC3000Client: public WiFiClient {
public:
    CC3000Client(Adafruit_CC3000& cc, Stream& stream=Serial);
    virtual ~CC3000Client();

    virtual int connect(IPAddress ip, uint16_t port);
    virtual int connect(const char *host, uint16_t port);
    virtual uint8_t connected();
    virtual int available();
    virtual void stop();
    virtual void flush();
    virtual int peek();
    virtual int read();
    virtual size_t write(uint8_t v);
    virtual size_t write(const uint8_t *buf, size_t size);
    virtual int read(uint8_t *buf, size_t size);
    virtual operator bool();

private:
    Adafruit_CC3000& cc3000;
    Adafruit_CC3000_Client client;
    bool peeked;
    int peeked_byte;
    Stream& stream;
};

The implementation is a bit tricky (or I didn't manage to find a better way), as the Adafruit client does not have peek() functionality, so this wrapper class have to implement it.

CC3000Client::CC3000Client(Adafruit_CC3000& cc, Stream& stre) :
        cc3000(cc), peeked(false), stream(stre), peeked_byte(0) {
}
CC3000Client::~CC3000Client() {
}

int CC3000Client::connect(IPAddress ip, uint16_t port) {
    client = cc3000.connectTCP((uint32_t) ip, port);
    peeked = false;
    if (client.connected())
        return 1;
    return 0;
}
int CC3000Client::connect(const char *host, uint16_t port) {
    uint32_t ip = 0;
    if (!cc3000.getHostByName((char*) host, &ip)) {
        stream.println(F("Couldn't resolve!"));
        return 0;
    }
    client = cc3000.connectTCP(ip, port);
    peeked = false;
    if (client.connected()) {
        return 1;
    }
    return 0;
}
uint8_t CC3000Client::connected() {
    return (uint8_t) client.connected();
}
int CC3000Client::available() {
    if(peeked)
        return 1;
    return (int) client.available();
}
void CC3000Client::stop() {
    peeked = false;
    flush();
    while (client.connected()){
        client.close();
        delay(10);
    }
}
void CC3000Client::flush() {
    peeked = false;
    while (connected() && available())
        read();
}
int CC3000Client::peek() {
    if (!peeked) {
        if (available()) {
            peeked_byte = read();
            peeked = true;
        } else
            return -1;
    }
    return peeked_byte;

}
int CC3000Client::read() {
    if (peeked) {
        peeked = false;
        return peeked_byte;
    }
    return (int) client.read();
}
size_t CC3000Client::write(uint8_t v) {
    return (size_t) client.write(v);
}
size_t CC3000Client::write(const uint8_t *buf, size_t size) {
    return client.write(buf, size);
}
int CC3000Client::read(uint8_t *buf, size_t size) {
    if(peeked){
        buf[0]=peeked_byte;
        peeked=false;
        return client.read(buf+1, size-1);
    }
    return client.read(buf, size);
}
CC3000Client::operator bool() {
    stream.println("Error, bool() not implemented");
    return true;
}

Both files are available here, if you are using biicode all you have to do in your code is to put an include like the following and run "bii find", that will also retrieve and install the cc3000 library:

#include "diego/ardunet/cc3000client.h"

I have used and tested it with a simple http_get call (also here) and with the temboo service, and it has worked OK for sending emails from a Gmail account from an Arduino Mega2560 connected to the CC3000. This temboo service uses via the SDK Client interface most methods of this wrapper, but the bool() operator and the CC3000Client::write(const uint8_t *buf, size_t size) method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.