Last active
August 29, 2015 14:02
-
-
Save circuitsenses/d74e6b56f4185cf8bf41 to your computer and use it in GitHub Desktop.
Arduino + Sparkfun Weather Shield + Adafruit CC3000 Shield IoT Demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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