Jump to content









Photo

Wireless Gardening with Arduino + CC3000 WiFi Modules

IoT Garden

  • Please log in to reply
39 replies to this topic

#1 jpastor

jpastor

    Development leader

  • Administrators
  • 159 posts

Posted 15 January 2014 - 12:08 PM

Hello everyone!

First of all, We want to thank our users for their inputs and suggestions. And of course, share their projects with us.

In this case, Marc-Olivier Schwartz has created an IoT garden using Carriots.

 

temperature_IMG_7844.jpg?1389347100

 

You can read more details about the project at http://learn.adafrui...es/introduction

 

Thanks Marc



Enjoy!



#2 pquade

pquade

    Newbie

  • Members
  • Pip
  • 6 posts

Posted 17 January 2014 - 09:51 PM

I'm trying to adapt this sketch to use the BMP180 pressure/temperature sensor from Adafruit.  Not that I have anything against gardening, I just don't have the sensor for it, but I do have the BMP180 which I've used for a couple of things so I know it works.

 

I believe I have it coded properly, but whenever I run it, the sketch seems to hang at the DHCP section and is only returning three of the four numbers required, "82.223.2".

 

Any ideas?



#3 pquade

pquade

    Newbie

  • Members
  • Pip
  • 6 posts

Posted 17 January 2014 - 10:00 PM

Oh, one more thing, in the tutorial it says I need my API key, but when I look under the Carriots "My Settings">"My Accounts" I see two; "Streams Read-only Apikey" and "Full Privileges Apikey".  I assume I should be using the "Full Privileges Apikey", but since I haven't quite gotten that far yet (still stuck at the DCHP issue above), I haven't been able to test that yet.



#4 pquade

pquade

    Newbie

  • Members
  • Pip
  • 6 posts

Posted 18 January 2014 - 06:49 AM

Resolved both issues.

 

I was able to upload dummy data I substituted for the gardening sensor and that worked.

Was able to configure the BMP180 data.  I'm not completely satisfied with it, but it's uploading.

 

Problem now is I'm getting an "unauthorized" message now back from the server I wasn't getting when I was successfully uploading dummy data.  Hmmm, don't know if I broke something or the system is just down right now.



#5 pquade

pquade

    Newbie

  • Members
  • Pip
  • 6 posts

Posted 18 January 2014 - 09:35 PM

Edited to clean it up a bit more.

 

/*************************************************** 
 * This is a sketch to interface a BMP180
 * using the Adafruit CC3000 breakout board (or WiFi shield)
 * 
 * Adapted from Marco Schwartz original work
 *  Adapted by Paul Quade
 *  Mostly changed the way sensor data is converted to Strings
 *  Also cleaned up a few random strings to use F() to save SRAM
 *  Also commented out some serial.print()s to save space
 ****************************************************/

// Libraries
#include <Adafruit_CC3000.h>  // http://www.adafruit.com/products/1469 
#include <SPI.h>
#include <Wire.h>
// This library also works with the BMP180
// and is Adafruit's reccomended library 
#include <Adafruit_BMP085.h>  // http://www.adafruit.com/products/1603

// Define CC3000 chip 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
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11

// I2C pins
const uint8_t dataPin  =  6;
const uint8_t clockPin =  7;

// Sensor variables
float t;
float h;

// Sensor
Adafruit_BMP085 bmp;

// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIV2); // you can change this clock speed

// WLAN parameters
#define WLAN_SSID       "yourSSID"         // cannot be longer than 32 characters!
#define WLAN_PASS       "yourPassword"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

// Xively parameters
#define WEBSITE  "api.carriots.com"
#define API_KEY  "yourApiKey"  // Use the Full Privileges Apikey
#define DEVICE   "yourDeviceName@yourUserName"

uint32_t ip;

void setup()
{
  // Initialize
  Serial.begin(115200);

  if (!bmp.begin()) {
    Serial.println(F("Couldn't begin BMP180.  Check wiring?"));
    while (1) {
    }
  }

  Serial.println(F("\nInitializing."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin CC3000.  Check wiring?"));
    while(1);
  }
}


void loop()
{
  // Connect to WiFi network
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("Connected!"));

  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100);
  }  

  // Get the website IP & print it
  ip = 0;
  Serial.print(WEBSITE); 
  Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve."));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);

  // Get data & transform to integers
  // Native output from BMP180 is SI units Centigrade and Pascals.
  t = bmp.readTemperature();
  t= (t*9/5)+32;               // Covenverts to from C to F
  h = bmp.readPressure();
  h = h * 0.000295299830714;   // Converts from pascals to inches of mercury

  // Convert Floats to Strings.
  char TempString[32];  //  A temporary character array to hold data.
  // dtostrf( [Float variable] , [Minimum SizeBeforePoint] , [sizeAfterPoint] , [WhereToStoreIt] )
  dtostrf(t,2,1,TempString);
  String temperature =  String(TempString);
  dtostrf(h,2,2,TempString);
  String pressure =  String(TempString);

  // Prepare JSON for Xively & get length
  int length = 0;

  String data = "{\"protocol\":\"v2\",\"device\":\""+String(DEVICE)+"\",\"at\":\"now\",\"data\":{\"Temperature\":"+String(temperature)+",\"Pressure\":"+String(pressure)+"}}";

  length = data.length();
  Serial.print(F("\nData length"));
  Serial.println(length);

  // Print request for debug purposes
  // Serial.println(F("POST /streams HTTP/1.1"));
  // Serial.println(F("Host: api.carriots.com"));
  // Serial.println(F("Accept: application/json"));
  // Serial.println(F("User-Agent: Arduino-Carriots"));
  // Serial.println(F("Content-Type: application/json"));
  Serial.print(F("carriots.apikey: "));
  Serial.println(String(API_KEY));
  Serial.print(F("Content-Length: "));
  Serial.println(String(length));
  Serial.println(F("Connection: close"));
  //Serial.println();
  Serial.println(data);

  // Send request
  Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
  if (client.connected()) {
    Serial.println(F("Connected!"));
    client.println(F("POST /streams HTTP/1.1"));
    client.println(F("Host: api.carriots.com"));
    client.println(F("Accept: application/json"));
    client.println(F("User-Agent: Arduino-Carriots"));
    client.println(F("Content-Type: application/json"));
    client.print(F("carriots.apikey: "));
    client.println(String(API_KEY));
    client.print(F("Content-Length: "));
    client.println(String(length));
    client.println(F("Connection: close"));
    client.println();
    client.println(data);
  } 
  else {
    Serial.println(F("Connection failed"));    
    return;
  }

  Serial.println(F("-------------------------------------"));
  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  client.close();
  Serial.println(F("\n-------------------------------------"));
  Serial.println(F("Disconnecting\n"));
  cc3000.disconnect();

  // Wait 60 seconds until next update
  delay(60000);
}


#6 nbansal79

nbansal79

    Newbie

  • Members
  • Pip
  • 1 posts

Posted 21 January 2014 - 12:31 AM

Hi I was trying the adafruit project. I am connecting to the server but getting the following:

 
Connecting to carbon...Waiting to connect...Connected!
Request DHCP
api.carriots.com -> 82.223.244.60Data length77
 
POST /streams HTTP/1.1
Host: api.carriots.com
Accept: application/json
User-Agent: Arduino-Carriots
Content-Type: application/json
carriots.apikey: {{{{{{ I have deleted the api key}}}}}
Content-Length: 77
Connection: close
{"protocol":"v2","device":"solarsensor","at":"now","data":{"Temperature":0.}}
 
 
Connect to 82.223.244.60:80
Connected!
-------------------------------------
HTTP/1.1 401 Unauthorized
Date: Tue, 21 Jan 2014 00:27:56 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 40
Connection: close
Server: TornadoServer/2.4
 
{ "response": "Not supported payload." }-------------------------------------
 
Any idea what I am doing wrong?
Thanks 
naren


#7 marcoschwartz

marcoschwartz

    Newbie

  • Members
  • Pip
  • 2 posts

Posted 21 January 2014 - 06:15 AM

Hello everyone,

 

I am the author of the guide on Adafruit, and it's great to see that people are trying to adapt my project with other sensors!

 

For the "Unauthorized" problem, it might be that you are not using the correct device name in the JSON data (from what I am seeing in the log that was posted). You really have to add your user name at the end like devicename@username. Let me know if that works.

 

Note that I also posted the guide on my website dedicated to Home Automation & Open-Source Hardware : 

 

http://www.openhomea...dening-arduino/

 

Cheers,

Marco Schwartz



#8 pquade

pquade

    Newbie

  • Members
  • Pip
  • 6 posts

Posted 22 January 2014 - 12:58 AM

Hi I was trying the adafruit project. I am connecting to the server but getting the following:

(snipped)

Connect to 82.223.244.60:80
Connected!
-------------------------------------
HTTP/1.1 401 Unauthorized
Date: Tue, 21 Jan 2014 00:27:56 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 40
Connection: close
Server: TornadoServer/2.4
 
{ "response": "Not supported payload." }-------------------------------------
 
Any idea what I am doing wrong?
Thanks 
naren

 

Naren,

 

I was having similar issues.  I attributed it to two things; I was adapting Marco's original code and SRAM crashing.

 

While I have no doubt Marco's sketch works perfectly as written, I believe it's pretty close to SRAM crashing without modifications.  The biggest issue is with the way Strings are used in the Arduino.

Here, take a look at this;

http://learn.adafrui...optimizing-sram

 

This is no dig at Marco in any way.  Strings on the Arduino are . . . awful.

 

Additionally, the doubleToString() function used also seemed to be giving me fits with my particular sensor data and was returning invalid data.  Fortunately, there is another way to go about it.  Check out my sketch above and look for the section commented as;

"// Convert Floats to Strings"

 

Again, no dig at Marco.  Marco had used a function that many other people have used for that.  It's well circulated, but I found it to be buggy with my data.

 

Marco did fantastic work and I never would have figured out how to get my data into any part of the cloud without the guidance of his sketch.  I'm sure others appreciate his efforts as well.



#9 pquade

pquade

    Newbie

  • Members
  • Pip
  • 6 posts

Posted 22 January 2014 - 01:07 AM

Hello everyone,

 

I am the author of the guide on Adafruit, and it's great to see that people are trying to adapt my project with other sensors!

 

Marco,

 

Thanks for pointing us in the right direction!  I couldn't have done it at all without your guidance.



#10 marcoschwartz

marcoschwartz

    Newbie

  • Members
  • Pip
  • 2 posts

Posted 23 January 2014 - 06:58 AM

Pquade, totally agree with you about Strings in Arduino, it's always a nightmare and you are most probably right about the SRAM problems.

 

Would be great if somebody would come up with an user-friendly & efficient JSON library that allows to easily integrate measurements & send them to a cloud service like Carriots. This way it will avoid all these problems due to data conversion.



#11 mcastillo

mcastillo

    Carriots CEO

  • Administrators
  • 34 posts
  • LocationMadrid

Posted 23 January 2014 - 08:39 AM

Would be great if somebody would come up with an user-friendly & efficient JSON library that allows to easily integrate measurements & send them to a cloud service like Carriots. This way it will avoid all these problems due to data conversion.

 

Hi Marco and Pquade,

 

We are working on those libraries to better integrate Arduino and Carriots. Those libraries will deal with data conversion and JSON structure. As soon as we have a Beta, we will publish them on Github.



#12 afterthought

afterthought

    Newbie

  • Members
  • Pip
  • 3 posts

Posted 30 January 2014 - 03:21 AM

Many thanks for Marco's sketch! 

I have some puzzles on the Data Stream List

Although I set the timezone, the times come out incorrect by 5 hours to the local time. Additionally, the repeated measurement data is not in correct temporal order. 

What am I missing?

Thanks for your reply



#13 amendoza

amendoza

    Master of Puppets

  • Members
  • PipPip
  • 10 posts

Posted 30 January 2014 - 10:17 AM

Many thanks for Marco's sketch! 

I have some puzzles on the Data Stream List

Although I set the timezone, the times come out incorrect by 5 hours to the local time. Additionally, the repeated measurement data is not in correct temporal order. 

What am I missing?

Thanks for your reply

 

Which is your time-zone in the control panel? You can check it in My Settings option at the top bar and then My Account.

 

When you send your streams, do you use a timestamp or "NOW"?



#14 afterthought

afterthought

    Newbie

  • Members
  • Pip
  • 3 posts

Posted 30 January 2014 - 09:16 PM

Thanks for your help.

1) I set up the time zone through DeviceManagment->Devices->TimeZone.

Following your suggestion, now I set up the Time Zone through My Setting ->My Account. I haven't tried it yet but  I guess that must have been the problem.

 

2) I have "now" in my stream. Why should that create a disordered timeline? (It does not create a problem because -in this case- it is not important. It may become important in a future application.

Thanks again



#15 KellyB

KellyB

    Newbie

  • Members
  • Pip
  • 1 posts

Posted 14 February 2014 - 02:11 PM

I'm completely stuck on this example

 

I changed the code to send two ints that decrease with every loop

It usually works the first time

But then the second time the program just stalls, usually after "Connected!"

And then I have to reset.

 

Any idea what the problem is?



#16 alvaro

alvaro

    Carriots CTO

  • Administrators
  • 72 posts

Posted 15 March 2014 - 11:15 AM

Hi KellyB.

 

It seems to be related to the Arduino sketch. If you don't have resolved it yet, can you post your code here? We will try to help you.

 

Enjoy Carriots!


Alvaro Everlet

Carriots CTO


#17 PineappleChili

PineappleChili

    Newbie

  • Members
  • Pip
  • 5 posts

Posted 16 July 2014 - 02:44 AM

Hey all! I am rather new to Arduino and am having problems with this project as well. As best I can tell, the heap is getting oddly fragmented at very random times. I added a counter to display each iteration through the loop to better figure out when it's crashing and it's pretty random. I've had it crash after one upload or crash after 150 uploads with a good number of random crashes in between. I've tried reserving the size of the strings when converting the floats to strings then just dropped them for ints so I wouldn't have to use the SRAM in the conversion at all. When it does crash, the data.length returns a value of 0, preventing the upload. I've attached my code below, with the sensitive data removed. If anyone could help point me in the right direction, I would be incredibly appreciative. This is my first foray into Arduino with only a light coding background and I'm worried I'm a bit over my head. :P

 

/*Plant Sensor v1.0
Receives humidity and temperature input from SHT-10 soil Sensor
Receives ambient temperature from DS18B20 temperature sensor
Displays data from sensors to LCD
Uploads data to Carriot via Adafruit CC3000 wifi shield
Refreshes every 10 minutes 
Based on code from M.Schwartz*/

//setting up the LCD screen
#include <LiquidCrystal.h>
// (rs, en, db4, db5, db6, db7)
LiquidCrystal dataDisplay(A0, A1, A2, A3, A4, A5);

//setting up WiFi
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include <stdlib.h>

#define ADAFRUIT_CC3000_IRQ   3
#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_DIVIDER);
#define WLAN_SSID "***"
#define WLAN_PASS "***"
#define WLAN_SECURITY WLAN_SEC_WPA2


//Setting up the humidity sensor
#include <SHT1x.h>
const uint8_t humidData = 8;
const uint8_t humidClock= 9;
uint8_t airTemp = 0;
uint8_t airHumid = 0;
SHT1x humidity(humidData, humidClock);

//setting up ambient temp
#include <OneWire.h>
#include <DallasTemperature.h>
const uint8_t ambientTemp = 7;
OneWire oneWire(ambientTemp);
DallasTemperature sensors(&oneWire);
uint8_t soilF = 0;

//setting up Carriots 
#define API_KEY "***"
#define DEVICE  "Soil_Sensor@PineappleChili.PineappleChili"
#define WEBSITE "api.carriots.com"
uint32_t ip;
String data = " ";
uint8_t length = 0;
uint16_t cycles = 0;


void setup () {
  Serial.begin(115200);

  //setting up LCD pins
  pinMode(A0, OUTPUT); 
  pinMode(A1, OUTPUT); 
  pinMode(A2, OUTPUT); 
  pinMode(A3, OUTPUT); 
  pinMode(A4, OUTPUT); 
  pinMode(A5, OUTPUT);
  
 //initiate sensors
  sensors.begin();
  
 //LCD load screen 
  dataDisplay.begin(4, 20);
  
  //connect to wifi
  cc3000.begin();
  Serial.println(F("Initializing CC3000"));
  if (!cc3000.begin()) {
    Serial.print(F("Failed"));
    while(1);
  }

//  data.reserve(200);
}



void loop () {
  cycles ++;
  Serial.print(F("Free RAM: ")); Serial.println(getFreeRam(), DEC);
  Serial.print(F("Attempting to connect to "));
  Serial.println(WLAN_SSID);
  cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
  Serial.println(F("Connected"));
    //Wait for DHCP to complete
  Serial.println(F("Requesting DHCP"));
  while (!cc3000.checkDHCP()) {
    delay(100);
  }
  Serial.println(F("DHCP complete"));

 //get website IP
    ip = 0;
  Serial.print(WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);
  Serial.println("");

 //read sensors
  airTemp = humidity.readTemperatureF();
  airHumid = humidity.readHumidity();
  sensors.requestTemperatures();
  soilF = ((sensors.getTempCByIndex(0) * 9)/5)+32;
  delay (1000);

//display sensors
  dataDisplay.clear();
  dataDisplay.print("Soil: ");
  dataDisplay.print(soilF);
  dataDisplay.print((char)223);
  dataDisplay.setCursor(0,1);
  dataDisplay.print("Air: ");
  dataDisplay.print(airTemp);
  dataDisplay.print((char) 223);
  dataDisplay.print(", ");
  dataDisplay.print(airHumid);
  dataDisplay.print("%");
  dataDisplay.setCursor(0,3);
  dataDisplay.print("Cycles: ");
  dataDisplay.print(cycles);


//upload - converting ints to strings for formatting
  Serial.println(F("Ram before conversion"));
  Serial.print(F("Free RAM: ")); Serial.println(getFreeRam(), DEC);
  String data = "{\"protocol\":\"v2\",\"device\":\""+String(DEVICE)+"\",\"at\":\"now\",\"data\":{\"Air Temperature\":"+airTemp+",\"Humidity\":"+airHumid+",\"Soil Temperature\":"+soilF+"}}";
  Serial.println(F("Ram after conversion"));
  Serial.print(F("Free RAM: ")); Serial.println(getFreeRam(), DEC);

 //verify via serial
  length = data.length();
//This is used for initial troubleshooting. Uncomment if your upload fails then verify content length here versus what is reported back from the client
  Serial.print(F("Data Length: "));
  Serial.print(length);
  Serial.println();
  Serial.println(F("POST /streams HTTP/1.1"));
  Serial.println(F("Host: api.carriots.com"));
  Serial.println(F("Accept: application/json"));
  Serial.println(F("User-Agent: Arduino-Carriots"));
  Serial.println(F("Content-Type: application/json"));
  Serial.println("carriots.apikey: " + String(API_KEY));
  Serial.println("Content-Length: " + String(length));
  Serial.print(F("Connection: close"));
  Serial.println();
  Serial.println(data);
  
  //send data
    Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
  if (client.connected()) {
  Serial.println(F("Connected!"));
    client.println("POST /streams HTTP/1.1");
    client.println("Host: api.carriots.com");
    client.println("Accept: application/json");
    client.println("User-Agent: Arduino-Carriots");
    client.println("Content-Type: application/json");
    client.println("carriots.apikey: " + String(API_KEY));
    client.println("Content-Length: " + String(length));
    client.println("Connection: close");
    client.println();
    client.println(data);
      Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);

  } else {
    Serial.println(F("Connection failed"));
    return;
  }
  
  Serial.println(F("----"));
  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  client.close();
  Serial.println(F("----"));
  Serial.println(F("\nDisconnecting"));
  cc3000.disconnect();
  
  Serial.println(F("Ram at end of loop"));
  Serial.print(F("Free RAM: ")); Serial.println(getFreeRam(), DEC);

delay (550000);

}

I call for free ram pretty frequently to pin down where it's leaking out and it's clear it occurs when the sensor data is added to the string but reserving the full data string doesn't allow me to upload (it reads the length as 0 so the upload fails). I know where the leak is occurring, I just have no idea how to stop it.



#18 jpastor

jpastor

    Development leader

  • Administrators
  • 159 posts

Posted 16 July 2014 - 06:39 AM

Hi PineappleChili

 

We will try to reproduce your code and help you, but we do not have all the hardware you use.

Maybe Marc, or a Carriots's friend that use your same components can help you.

Are you using an Arduino One or Arduino Mega?



#19 PineappleChili

PineappleChili

    Newbie

  • Members
  • Pip
  • 5 posts

Posted 16 July 2014 - 02:43 PM

Thanks jpastor! Any help would be greatly appreciated. I'm currently using an Uno but am thinking of expanding the project to include a CO2 and soil humidity sensor (once the memory leaks are fixed) so I'll likely upgrade the project to a Mega soon. I know I'm getting close to hitting the limits of the memory on the Uno since it's at around 28.4 when I compile.



#20 jpastor

jpastor

    Development leader

  • Administrators
  • 159 posts

Posted 16 July 2014 - 03:47 PM

It would be perfect if you could test the code with Arduino Mega, often these problems disappear.

Anyway we will try to collect all the hardware you use and reproduce your code.






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users