Please be aware of all shipping deadlines before placing your order - we cannot guarantee orders will arrive before Christmas!

CC300 weather station
Moderators: adafruit_support_bill, adafruit

Re: CC300 weather station

by adafruit_support_mike on Sun Feb 09, 2014 12:57 am

The access log shows a status code of 200 (Successful Transfer) for all the requests in that series, and the number of bytes sent as output is the same for every request.

The error log shows that you have a couple of problems with the PHP page itself.. the values 'smc' and 'light' on lines 19 and 20 aren't being defined properly. Take a look at the code there and see what's going on.

If the display reads 'Initializing', execution has folded back to the 'setup()' function, which happens for one of two reasons: a glitch in the power that causes the Arduino to do a hardware reset, or memory overrun problems that cause a software reset.
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 11367
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

by mh512 on Sun Feb 09, 2014 8:12 pm

Yup, i'm not sending any data to the server in the get request for light and smc so that's where that comes from.

I think it must be an issue with the arduino memory then.
mh512
 
Posts: 38
Joined: Wed Nov 13, 2013 4:06 pm

Re: CC300 weather station

by adafruit_support_mike on Sun Feb 09, 2014 8:42 pm

That's possible. Try stripping the code down as much as you can, and see if the problem goes away. The Arduino String class tends to be bulky, so limiting your use of that can help.
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 11367
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

by mh512 on Tue Feb 11, 2014 10:22 am

The arduino does not always go back to setup at the same time it stops sending data.

Definitely a memory issue. Any tips for reducing the SRAM usage? I should've bought a mega

If the string class is so clunky is there any other way to send the 2 ints to the php script?

I've just run a script doing everything minus the display and it will keep going forever.

I still think this is odd because I had it working yesterday display et al
mh512
 
Posts: 38
Joined: Wed Nov 13, 2013 4:06 pm

Re: CC300 weather station

by pocketmoon on Tue Feb 11, 2014 6:37 pm

Hi,

For SRAM one option is to add an external SRAM chip, something like a 23K256 ( 32Kbytes, 3.3v, good for trinket) or a 23LV1024 (128Kbytes, 5v , good for Uno etc). You can talk to these little gems using SPI and it's pretty simple to code read/write byte and read/write sequential buffers.

So you can buffer data up in scarce 'local' SRAM and then write it out to the external chip. I'm using a CC3000 to read tweets (in a roundabout way!) and I buffer these in SRAM for subsequent display.

Cheers

Rob
pocketmoon
 
Posts: 59
Joined: Fri Dec 27, 2013 8:21 pm

Re: CC300 weather station

by adafruit_support_mike on Wed Feb 12, 2014 5:25 pm

mh512 wrote:If the string class is so clunky is there any other way to send the 2 ints to the php script?

You can use C strings, which are just char arrays:

Code: Select all | TOGGLE FULL SIZE
char buffer[32];

sptrintf( buffer, "var1=%s; var2=%s", var1, var2);

You may need to add the string library:

Code: Select all | TOGGLE FULL SIZE
#include <string.h>

but compared to String, it isn't a bad trade.

Also try allocating a single, global buffer and using that every time you need to format some text. You trade a slightly higher amount of heap storage for a lot less storage on the stack. Also use the F() macro for any fixed strings. That stores information in Flash, which is much larger than the RAM.
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 11367
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

by mh512 on Mon Feb 17, 2014 10:08 am

Thanks Mike

Can you show me how to do this bit with the F macro and string method you describe please?

Code: Select all | TOGGLE FULL SIZE
   // Transform to String
    String temperature = String((int) t);
    String humidity = String((int) h);

    // Send request
    String request = "GET "+ repository + "submit.php?temp=" + temperature + "&hum=" + humidity + " HTTP/1.0";
    send_request(request);


Thanks
mh512
 
Posts: 38
Joined: Wed Nov 13, 2013 4:06 pm

Re: CC300 weather station

by adafruit_support_mike on Mon Feb 17, 2014 11:49 pm

I'd do it like this:

Code: Select all | TOGGLE FULL SIZE
   char buffer[ BUFSIZE ] = "";
   sprintf(
      F("GET %s/submit.php?temp=%.1f&hum=%.1f HTTP/1.0"),
      F("http://machine.network.tld"),
      temperature, humidity
   );

with 'BUFSIZE' set so it's large enough to hold the entire request.

You can save memory on the stack by making 'buffer[]' a global variable and using the same block of heap storage over and over again.
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 11367
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

by mh512 on Tue Feb 18, 2014 4:12 pm

Thanks I will give that a go

Does it need to go within send_request()?
mh512
 
Posts: 38
Joined: Wed Nov 13, 2013 4:06 pm

Re: CC300 weather station

by adafruit_support_mike on Wed Feb 19, 2014 12:29 am

You'd just send the variable 'buffer'. To make that work you'll need to modify the code slightly:

Code: Select all | TOGGLE FULL SIZE
void send_request (String request) {

needs to be:

Code: Select all | TOGGLE FULL SIZE
void send_request (const char request[]) {

but then all you need to do is pass the character buffer as usual:

Code: Select all | TOGGLE FULL SIZE
send_request( buffer );
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 11367
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

by mh512 on Wed Feb 19, 2014 5:10 pm

Hi Mike

I have the following code but I get this error for the sprintf line:

Code: Select all | TOGGLE FULL SIZE
error: cannot convert 'const __FlashStringHelper*' to 'char*' for argument '1' to 'int sprintf(char*, const char*, ...)'


I'm a little confused as to how the sprintf result gets put into the string 'buffer' as the code doesn't seem to be doing anything with the result.

Thanks

Code: Select all | TOGGLE FULL SIZE
// Include required libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include "DHT.h"
#include <stdlib.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

char buffer[ 500 ] = "";

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// WLAN settings
#define WLAN_SSID       "TP-LINK AP"
#define WLAN_PASS       "password"
#define WLAN_SECURITY   WLAN_SEC_WPA2

// DHT11 pin configuration
#define DHTPIN 2
#define DHTTYPE DHT11

// Create instances
DHT dht(DHTPIN, DHTTYPE);
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();

//LCD setup
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
                                       
// Local server IP, port, and repository
uint32_t ip = cc3000.IP2U32(192,168,0,100);
int port = 80;
String repository = "/";

//Define matrix shapes
static const uint8_t PROGMEM
  smile_bmp[] =
  { B00111100,
    B01000010,
    B10100101,
    B10000001,
    B10100101,
    B10011001,
    B01000010,
    B00111100 };
                                       
void setup(void)
{
 matrix.begin(0x70);
 matrix.setBrightness(1);
 lcd.begin(16,2);
 dht.begin();
 //Serial.begin(115200);
 
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(F("Initialising..."));
       
  if (!cc3000.begin())
  {
    while(1);
  }

  lcd.clear();
  lcd.print(F("Connecting..."));

  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
 
  while (!cc3000.checkDHCP())
  {
    delay(100);
  } 
 
  lcd.clear();
  lcd.print(F("Connected!"));
 
}

void loop(void)
{
 
  matrix.clear();
  matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);
  matrix.writeDisplay(); 
   
  float h = dht.readHumidity();
  float t = dht.readTemperature();
   
    //Print humidity & temperature on LCD display   
    if (isnan(t) || isnan(h)) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("No data!"));
    }
    else {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("Data ok!"));
    }
     
    // Transform to String
    String temperature = String((int) t);
    String humidity = String((int) h);
     
   
    sprintf(F("GET /submit.php?temp%.1f&hum=%.1f HTTP/1.0"), temperature, humidity);
             
    send_request( buffer );
   
    // Update every second
    delay(1000);
}

// Function to send a TCP request and get the result as a string
void send_request (const char request[]) {
     
    // Connect   
    Adafruit_CC3000_Client client = cc3000.connectTCP(ip, port);
   
    // Send request
   
      client.println(request);     
      client.println(F(""));
       
    while (client.connected()) {
      while (client.available()) {

      char c = client.read();
      }
    }
   
    client.close();
   
}
mh512
 
Posts: 38
Joined: Wed Nov 13, 2013 4:06 pm

Re: CC300 weather station

by adafruit_support_mike on Thu Feb 20, 2014 1:00 am

I mistyped the first example.. the char buffer should be the first argument to 'sprintf()'.. and it looks like you need a plain C string for the template.

Try this:

Code: Select all | TOGGLE FULL SIZE
    sprintf(buffer, "GET /submit.php?temp%.1f&hum=%.1f HTTP/1.0", temperature, humidity);
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 11367
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

by mh512 on Thu Feb 20, 2014 4:48 pm

Thanks

The code below compiles but the server is not receiving the data.

Code: Select all | TOGGLE FULL SIZE
/*
*  DigiPlant environment monitor sketch
*/

// Include required libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include "DHT.h"
#include <stdlib.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// WLAN settings
#define WLAN_SSID       "TP-LINK AP"
#define WLAN_PASS       "password"
#define WLAN_SECURITY   WLAN_SEC_WPA2

// DHT11 pin configuration
#define DHTPIN 2
#define DHTTYPE DHT11

// Create instances
DHT dht(DHTPIN, DHTTYPE);
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();

//LCD setup
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
                                       
// Local server IP, port, and repository
uint32_t ip = cc3000.IP2U32(192,168,0,100);
int port = 80;

//Define matrix shapes
static const uint8_t PROGMEM
  smile_bmp[] =
  { B00111100,
    B01000010,
    B10100101,
    B10000001,
    B10100101,
    B10011001,
    B01000010,
    B00111100 };
   
//request char buffer
char buffer [1000] = "";
                                     
void setup(void)
{
 matrix.begin(0x70);
 matrix.setBrightness(1);
 
 lcd.begin(16,2);
 dht.begin();
 
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(F("Initialising..."));
       
  if (!cc3000.begin())
  {
    while(1);
  }

  lcd.clear();
  lcd.print(F("Connecting..."));

  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
 
  while (!cc3000.checkDHCP())
  {
    delay(100);
  } 
 
  lcd.clear();
  lcd.print(F("Connected!"));
 
}

void loop(void)
{
 
  matrix.clear();
  matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);
  matrix.writeDisplay(); 
   
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  int l = analogRead(A0);
   
    //Print humidity & temperature on LCD display   
    if (isnan(t) || isnan(h)) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("No data!"));
    }
    else {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("Data ok!"));
    }
     
    // Transform to String
    String temperature = String((int) t);
    String humidity = String((int) h);
    String light = String((int) l);
     
     
     
    sprintf(buffer, "GET /submit.php?temp=%.1f&hum=%.1f&light=%.1f HTTP/1.0", temperature, humidity, light);
   
   
   
   
    send_request(buffer);
   
    delay(1000);
}

// Function to send a TCP request and get the result as a string
void send_request (const char request[]) {
     
    // Connect   
    Adafruit_CC3000_Client client = cc3000.connectTCP(ip, port);
   
    // Send request
   
      client.println(request);     
      client.println(F(""));
       
    while (client.connected()) {
      while (client.available()) {

      char c = client.read();
      }
    }
   
    client.close();
   
}


For reference, this is the code using the old method that works:
Code: Select all | TOGGLE FULL SIZE
/*
*  DigiPlant environment monitor sketch
*/

// Include required libraries
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include "DHT.h"
#include <stdlib.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ   3
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

// WLAN settings
#define WLAN_SSID       "TP-LINK AP"
#define WLAN_PASS       "password"
#define WLAN_SECURITY   WLAN_SEC_WPA2

// DHT11 pin configuration
#define DHTPIN 2
#define DHTTYPE DHT11

// Create instances
DHT dht(DHTPIN, DHTTYPE);
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2);
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();

//LCD setup
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
                                       
// Local server IP, port, and repository
uint32_t ip = cc3000.IP2U32(192,168,0,100);
int port = 80;

//Define matrix shapes
static const uint8_t PROGMEM
  smile_bmp[] =
  { B00111100,
    B01000010,
    B10100101,
    B10000001,
    B10100101,
    B10011001,
    B01000010,
    B00111100 };
                                     
void setup(void)
{
 matrix.begin(0x70);
 matrix.setBrightness(1);
 
 lcd.begin(16,2);
 dht.begin();
 //Serial.begin(115200);
 
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(F("Initialising..."));
       
  if (!cc3000.begin())
  {
    while(1);
  }

  lcd.clear();
  lcd.print(F("Connecting..."));

  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
 
  while (!cc3000.checkDHCP())
  {
    delay(100);
  } 
 
  lcd.clear();
  lcd.print(F("Connected!"));
 
}

void loop(void)
{
 
  matrix.clear();
  matrix.drawBitmap(0, 0, smile_bmp, 8, 8, LED_ON);
  matrix.writeDisplay(); 
   
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  int l = analogRead(A0);
   
    //Print humidity & temperature on LCD display   
    if (isnan(t) || isnan(h)) {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("No data!"));
    }
    else {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(F("Data ok!"));
    }
     
    // Transform to String
    String temperature = String((int) t);
    String humidity = String((int) h);
    String light = String((int) l);
     
   
    // Send request
    String request = "GET /submit.php?temp=" + temperature + "&hum=" + humidity + "&light=" + light + " HTTP/1.0";
    send_request(request);
   
    delay(1000);
}

// Function to send a TCP request and get the result as a string
void send_request (String request) {
     
    // Connect   
    Adafruit_CC3000_Client client = cc3000.connectTCP(ip, port);
   
    // Send request
   
      client.println(request);     
      client.println(F(""));
       
    while (client.connected()) {
      while (client.available()) {

      char c = client.read();
      }
    }
   
    client.close();
   
}


It's definitely worth doing because the sketch size drops by about 5k!
mh512
 
Posts: 38
Joined: Wed Nov 13, 2013 4:06 pm

Re: CC300 weather station

by adafruit_support_mike on Thu Feb 20, 2014 11:59 pm

A couple of minor points..

First, you don't need these conversions any more:

Code: Select all | TOGGLE FULL SIZE
    // Transform to String
    String temperature = String((int) t);
    String humidity = String((int) h);
    String light = String((int) l);

'sprintf()' knows how to convert numbers to text, so you don't need the intermediate Strings any more.

Second, it's best to match the output descriptor to the data type:

Code: Select all | TOGGLE FULL SIZE
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  int l = analogRead(A0);
  //*  ...  */
    sprintf(buffer, "GET /submit.php?temp=%.1f&hum=%.1f&light=%d HTTP/1.0", t, h, l);

The '%f' marker indicates a floating point number, the '%d' marker indicates an integer value.

You can probably crank the size of the buffer way down too.. 1000 bytes is a lot more than you need for an HTTP request.

All that aside, I'm not sure why the data wouldn't pass through to the server. What are you getting in the httpd logs?
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.
User avatar
adafruit_support_mike
 
Posts: 11367
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

by mh512 on Sat Feb 22, 2014 1:35 pm

adafruit_support_mike wrote:A couple of minor points..

First, you don't need these conversions any more:

Code: Select all | TOGGLE FULL SIZE
    // Transform to String
    String temperature = String((int) t);
    String humidity = String((int) h);
    String light = String((int) l);

'sprintf()' knows how to convert numbers to text, so you don't need the intermediate Strings any more.


Removing that bit and using t, h and l in sprintf increases the sketch size by about 4k.

Changing this line:
Code: Select all | TOGGLE FULL SIZE
sprintf(buffer, "GET /submit.php?temp=%s&hum=%s&light=%s HTTP/1.0", temperature, humidity, light);

to this:
Code: Select all | TOGGLE FULL SIZE
sprintf(buffer, "GET /submit.php?temp=%.1f&hum=%.1f&light=%d HTTP/1.0", t, h, l);

increases the sketch size considerably.

Problem is, the bottom one works and the top one doesn't.

Not sure on this one...

Thanks
mh512
 
Posts: 38
Joined: Wed Nov 13, 2013 4:06 pm