CC300 weather station
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- adafruit_support_mike
- Posts: 67485
- Joined: Thu Feb 11, 2010 2:51 pm
Re: CC300 weather station
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.
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.
-
- Posts: 76
- Joined: Wed Nov 13, 2013 4:06 pm
Re: CC300 weather station
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.
I think it must be an issue with the arduino memory then.
- adafruit_support_mike
- Posts: 67485
- Joined: Thu Feb 11, 2010 2:51 pm
Re: CC300 weather station
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.
-
- Posts: 76
- Joined: Wed Nov 13, 2013 4:06 pm
Re: CC300 weather station
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
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
- pocketmoon
- Posts: 78
- Joined: Fri Dec 27, 2013 8:21 pm
Re: CC300 weather station
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
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
- adafruit_support_mike
- Posts: 67485
- Joined: Thu Feb 11, 2010 2:51 pm
Re: CC300 weather station
You can use C strings, which are just char arrays:mh512 wrote:If the string class is so clunky is there any other way to send the 2 ints to the php script?
Code: Select all
char buffer[32];
sptrintf( buffer, "var1=%s; var2=%s", var1, var2);
Code: Select all
#include <string.h>
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.
-
- Posts: 76
- Joined: Wed Nov 13, 2013 4:06 pm
Re: CC300 weather station
Thanks Mike
Can you show me how to do this bit with the F macro and string method you describe please?
Thanks
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);
- adafruit_support_mike
- Posts: 67485
- Joined: Thu Feb 11, 2010 2:51 pm
Re: CC300 weather station
I'd do it like this:
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.
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
);
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.
-
- Posts: 76
- Joined: Wed Nov 13, 2013 4:06 pm
Re: CC300 weather station
Thanks I will give that a go
Does it need to go within send_request()?
Does it need to go within send_request()?
- adafruit_support_mike
- Posts: 67485
- Joined: Thu Feb 11, 2010 2:51 pm
Re: CC300 weather station
You'd just send the variable 'buffer'. To make that work you'll need to modify the code slightly:
needs to be:
but then all you need to do is pass the character buffer as usual:
Code: Select all
void send_request (String request) {
Code: Select all
void send_request (const char request[]) {
Code: Select all
send_request( buffer );
-
- Posts: 76
- Joined: Wed Nov 13, 2013 4:06 pm
Re: CC300 weather station
Hi Mike
I have the following code but I get this error for the sprintf line:
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
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*, ...)'
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();
}
- adafruit_support_mike
- Posts: 67485
- Joined: Thu Feb 11, 2010 2:51 pm
Re: CC300 weather station
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:
Try this:
Code: Select all
sprintf(buffer, "GET /submit.php?temp%.1f&hum=%.1f HTTP/1.0", temperature, humidity);
-
- Posts: 76
- Joined: Wed Nov 13, 2013 4:06 pm
Re: CC300 weather station
Thanks
The code below compiles but the server is not receiving the data.
For reference, this is the code using the old method that works:
It's definitely worth doing because the sketch size drops by about 5k!
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();
}
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();
}
- adafruit_support_mike
- Posts: 67485
- Joined: Thu Feb 11, 2010 2:51 pm
Re: CC300 weather station
A couple of minor points..
First, you don't need these conversions any more:
'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:
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?
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);
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);
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?
-
- Posts: 76
- Joined: Wed Nov 13, 2013 4:06 pm
Re: CC300 weather station
Removing that bit and using t, h and l in sprintf increases the sketch size by about 4k.adafruit_support_mike wrote:A couple of minor points..
First, you don't need these conversions any more:
'sprintf()' knows how to convert numbers to text, so you don't need the intermediate Strings any more.Code: Select all
// Transform to String String temperature = String((int) t); String humidity = String((int) h); String light = String((int) l);
Changing this line:
Code: Select all
sprintf(buffer, "GET /submit.php?temp=%s&hum=%s&light=%s HTTP/1.0", temperature, humidity, light);
Code: Select all
sprintf(buffer, "GET /submit.php?temp=%.1f&hum=%.1f&light=%d HTTP/1.0", t, h, l);
Problem is, the bottom one works and the top one doesn't.
Not sure on this one...
Thanks
Please be positive and constructive with your questions and comments.