CC300 weather station

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

Post by adafruit_support_mike »

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.

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

Re: CC300 weather station

Post by mh512 »

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.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

Post by adafruit_support_mike »

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.

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

Re: CC300 weather station

Post by mh512 »

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

User avatar
pocketmoon
 
Posts: 78
Joined: Fri Dec 27, 2013 8:21 pm

Re: CC300 weather station

Post by pocketmoon »

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

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

Post by adafruit_support_mike »

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

char buffer[32];

sptrintf( buffer, "var1=%s; var2=%s", var1, var2);
You may need to add the string library:

Code: Select all

#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.

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

Re: CC300 weather station

Post by mh512 »

Thanks Mike

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

Code: Select all

   // 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

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

Post by adafruit_support_mike »

I'd do it like this:

Code: Select all

	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.

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

Re: CC300 weather station

Post by mh512 »

Thanks I will give that a go

Does it need to go within send_request()?

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

Post by adafruit_support_mike »

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

Code: Select all

void send_request (String request) {
needs to be:

Code: Select all

void send_request (const char request[]) {
but then all you need to do is pass the character buffer as usual:

Code: Select all

send_request( buffer );

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

Re: CC300 weather station

Post by mh512 »

Hi Mike

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

Code: Select all

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

// 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();
    
}

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

Post by adafruit_support_mike »

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

    sprintf(buffer, "GET /submit.php?temp%.1f&hum=%.1f HTTP/1.0", temperature, humidity);

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

Re: CC300 weather station

Post by mh512 »

Thanks

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

Code: Select all

/* 
*  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

/* 
*  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!

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: CC300 weather station

Post by adafruit_support_mike »

A couple of minor points..

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

Code: Select all

    // 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

  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?

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

Re: CC300 weather station

Post by mh512 »

adafruit_support_mike wrote:A couple of minor points..

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

Code: Select all

    // 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

sprintf(buffer, "GET /submit.php?temp=%s&hum=%s&light=%s HTTP/1.0", temperature, humidity, light);
to this:

Code: Select all

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

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”