Skip to content

Instantly share code, notes, and snippets.

@circuitsenses
Last active August 29, 2015 14:02
Show Gist options
  • Save circuitsenses/d74e6b56f4185cf8bf41 to your computer and use it in GitHub Desktop.
Save circuitsenses/d74e6b56f4185cf8bf41 to your computer and use it in GitHub Desktop.
Arduino + Sparkfun Weather Shield + Adafruit CC3000 Shield IoT Demo
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#include <Wire.h> // I2C needed for sensors
#include "MPL3115A2.h" // Pressure sensor
#include "HTU21D.h" // Humidity sensor
// These are the interrupt and control 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
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIVIDER); // you can change this clock speed but DI
#define WLAN_SSID "YourNetwork" // cannot be longer than 32 characters!
const char WLAN_PASS[] = "YourPass"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY "YourSecurityMode"
MPL3115A2 myPressure; //Create an instance of the pressure sensor
HTU21D myHumidity; //Create an instance of the humidity sensor
const byte STAT1 = 7;
const byte STAT2 = 8;
const byte LIGHT = A1;
const byte REFERENCE_3V3 = A3;
float humidity = 0; // [%]
float tempf = 0; // [temperature F]
float pressure = 0;
float light_lvl = 455; //[analog value from 0 to 1023]
#define WEBSITE F("api.xively.com")
#define API_key F("YourKey")
#define feedID F("YourFeedID")
uint32_t ip = 0;
/**************************************************************************/
/*!
@brief Displays the driver mode (tiny of normal), and the buffer
size if tiny mode is not being used
@note The buffer size and driver mode are defined in cc3000_common.h
*/
/**************************************************************************/
void displayDriverMode(void)
{
#ifdef CC3000_TINY_DRIVER
Serial.println(F("CC3000 is configure in 'Tiny' mode"));
#else
#ifdef SERDEBUG
Serial.print(F("RX Buffer : "));
Serial.print(CC3000_RX_BUFFER_SIZE);
Serial.println(F(" bytes"));
Serial.print(F("TX Buffer : "));
Serial.print(CC3000_TX_BUFFER_SIZE);
Serial.println(F(" bytes"));
#endif
#endif
}
/**************************************************************************/
/*!
@brief Tries to read the CC3000's internal firmware patch ID
*/
/**************************************************************************/
uint16_t checkFirmwareVersion(void)
{
uint8_t major, minor;
uint16_t version;
#ifndef CC3000_TINY_DRIVER
if(!cc3000.getFirmwareVersion(&major, &minor))
{
Serial.println(F("Unable to retrieve the firmware version!\r\n"));
version = 0;
}
else
{
Serial.print(F("Firmware V. : "));
Serial.print(major); Serial.print(F(".")); Serial.println(minor);
version = major; version <<= 8; version |= minor;
}
#endif
return version;
}
/**************************************************************************/
/*!
@brief Tries to read the 6-byte MAC address of the CC3000 module
*/
/**************************************************************************/
void displayMACAddress(void)
{
uint8_t macAddress[6];
if(!cc3000.getMacAddress(macAddress))
{
#ifdef SERDEBUG
Serial.println(F("Unable to retrieve MAC Address!\r\n"));
#endif
}
else
{
Serial.print(F("MAC Address : "));
cc3000.printHex((byte*)&macAddress, 6);
}
}
/**************************************************************************/
/*!
@brief Tries to read the IP address and other connection details
*/
/**************************************************************************/
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
Serial.println(F("Unable to retrieve the IP Address!\r\n"));
return false;
}
else
{
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
//Returns the voltage of the light sensor based on the 3.3V rail
//This allows us to ignore what VCC might be (an Arduino plugged into USB has VCC of 4.5 to 5.2V)
float get_light_level()
{
float operatingVoltage = analogRead(REFERENCE_3V3);
float lightSensor = analogRead(LIGHT);
operatingVoltage = 3.3 / operatingVoltage; //The reference voltage is 3.3V
lightSensor = operatingVoltage * lightSensor;
return(lightSensor);
}
//Calculates each of the variables that wunderground is expecting
void calcWeather()
{
//Calc humidity
humidity = myHumidity.readHumidity();
//float temp_h = myHumidity.readTemperature();
//Serial.print(" TempH:");
//Serial.print(temp_h, 2);
//Calc tempf from pressure sensor
tempf = myPressure.readTempF();
// converting to centigrade.
// did not care to change variable name
tempf = (tempf - 32.0)/1.8000;
//Calc pressure
// Could not use this due to memory limitations on Arduino
// when forming the JSON string.
pressure = (myPressure.readPressure())/100000;
//Calc light level
// Multipled by 100 to get proper display on Xiv
// values were too small
light_lvl = get_light_level() * 100;
}
void setup(void)
{
Serial.begin(9600);
Serial.println(F("Hello, CC3000!\n"));
displayDriverMode();
Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
/* Initialise the module */
Serial.println(F("\nInitialising the CC3000 ..."));
if (!cc3000.begin())
{
Serial.println(F("Unable to initialise the CC3000! Check your wiring?"));
while(1);
}
uint16_t firmware = checkFirmwareVersion();
if (firmware < 0x113) {
Serial.println(F("Wrong firmware version!"));
for(;;);
}
displayMACAddress();
/* Delete any old connection data on the module */
Serial.println(F("\nDeleting old connection profiles"));
if (!cc3000.deleteProfiles()) {
Serial.println(F("Failed!"));
while(1);
}
/* Attempt to connect to an access point */
char *ssid = WLAN_SSID; /* Max 32 chars */
Serial.print(F("\nAttempting to connect to ")); Serial.println(ssid);
/* NOTE: Secure connections are not available in 'Tiny' mode! */
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while(1);
}
Serial.println(F("Connected!"));
/* Wait for DHCP to complete */
Serial.println(F("Request DHCP"));
while (!cc3000.checkDHCP())
{
delay(100); // ToDo: Insert a DHCP timeout!
}
/* Display the IP address DNS, Gateway, etc. */
while (! displayConnectionDetails()) {
delay(1000);
}
Serial.println();
ip = cc3000.IP2U32(216,52,233,120);
cc3000.printIPdotsRev(ip);
Serial.println();
Serial.println(F("Wi-Fi Online"));
Serial.println(F("Initializing Weather Shield"));
pinMode(STAT1, OUTPUT); //Status LED Blue
pinMode(REFERENCE_3V3, INPUT);
pinMode(LIGHT, INPUT);
//Configure the pressure sensor
myPressure.begin(); // Get sensor online
myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
myPressure.setOversampleRate(7); // Set Oversample to the recommended 128
myPressure.enableEventFlags(); // Enable all three pressure and temp event flags
//Configure the humidity sensor
myHumidity.begin();
Serial.println(F("Weather Shield online!"));
/* You need to make sure to clean up after yourself or the CC3000 can freak out */
/* the next time you try to connect ... */
// Serial.println(F("\n\nClosing the connection"));
// cc3000.disconnect();
}
void loop() {
digitalWrite(STAT1, HIGH); //Blink stat LED
calcWeather();
// Prepare JSON for Xively & get length
int length = 0;
String data = "";
//data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"Temperature\",\"current_value\" : \"" + String((int)tempf) + "\"}," + "{\"id\" : \"Humidity\",\"current_value\" : \"" + String((int)humidity) + "\"}," + "{\"id\" : \"Pressure\",\"current_value\" : \"" + String((int)pressure) + "\"}," + "{\"id\" : \"Luminosity\",\"current_value\" : \"" + String((int)light_lvl) + "\"}]}";
data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"Temperature\",\"current_value\" : \"" + String(tempf) + "\"},"
+ "{\"id\" : \"Humidity\",\"current_value\" : \"" + String(humidity) + "%" + "\"}," //]}";
+ "{\"id\" : \"Luminosity\",\"current_value\" : \"" + String(light_lvl) + "\"}]}";
length = data.length();
#ifdef SERDEBUG
// Print request for debug purposes
Serial.print("PUT /v2/feeds/");
Serial.print(feedID);
Serial.println(".json HTTP/1.0");
Serial.println("Host: api.xively.com");
Serial.print("X-ApiKey: ");
Serial.println(API_key);
Serial.print("Content-Length: ");
Serial.println(length, DEC);
Serial.print("Connection: close");
Serial.println();
Serial.print(data);
Serial.println();
#endif
// Send request
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected()) {
Serial.println("Connected!");
// Starting here, till...
client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
client.println("Host: api.xively.com");
client.println("X-ApiKey: " + String(API_key));
client.println("Content-Length: " + String(length));
client.print("Connection: close");
client.println();
client.print(data);
client.println();
// ... here, the process takes approx. 40 seconds !!!
digitalWrite(STAT1, LOW); //Blink stat LED
} 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("-------------------------------------"));
delay(100);
// Yep, i do not disconnect.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment