-->
Page 1 of 1

Simple posting of Sensor Data to Thingspeak (simple GET)

PostPosted: Thu Dec 24, 2015 11:07 am
by GengusKahn
This sketch also Tweets some sensor readings every 15 minutes, dependant on the timing of the Thingspeak Post (60 posts @ 15 seconds per 1 tweet).

This is using a BMP180 and MPU6050 on Pins 4+5 with the HC5883 on XCL + XDA of MPU6050, on an ESP8266-12
If the interrupt from the MPU or Compass is to be used, use pin15.....

The twitter.h file has been modified for the ESP included here also......

The Sketch...

Code: Select all/*  Modified for easy ESP8266 use December 19 2015


♀♪♂


<iframe width="450" height="260" style="border: 1px solid #cccccc;" src="http://api.thingspeak.com/channels/XXXXX/charts/Y?width=450&height=260&results=ZZ&dynamic=true" ></iframe>

Embed this in any html to see the output Replacing the XXXXX with Your Channel Number, Y with the Chart "&fieldY=" to display and ZZ with the number of readings to retrieve.

*/



#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <Twitter.h>
#include <Wire.h>
#include <HMC5883L.h>
#include <MPU6050.h>
#include <SFE_BMP180.h>
double baseline; // baseline pressure
SFE_BMP180 pressure;
#define ALTITUDE 30.0           // Meters above Sea level
double T,a,P,p0;

HMC5883L compass;

MPU6050 mpu;

// Timers
unsigned long timer = 0;
float timeStep = 0.01;

// Pitch, Roll and Yaw values
float pitch = 0;
float roll = 0;
float yaw = 0;

int previousDegree;

// Set time compare to select post rather than delay.......
unsigned long ulMeasDelta_ms;  // Distance to Tweet Time Timer
unsigned long ulNextMeas_ms;   // Holder for the next Tweet Time Value
int loop_timer = 15;           // Set the delay in Seconds for Thingspeak
int tweet_timer = 60;          // The number of 15 second periods to wait before Tweeting
int tweet_count = 0;           // Loop to cout thing posts
int i=1;                        // How many Tweets
// Remember the transaction takes time to negotiate ....
// So for faster updates than 1 Second use a Stream and separate Twitter......
char buf[120];                  // The Tweet

WiFiServer server(80);
WiFiClient client;
Twitter twitter("Your-Twitter API_KEY");                                   // Twitter API Key
const char* thingspeak_key = "Your-API_KEY";                      // Thingspeak API Write Key Channel 1
const char* thingspeak_key1 = "Your-API_KEY";                     // Thingspeak API Write Key Channel 2
const char* ssid = "Your SSID";
const char* password = "Your Password";
const char* hostts = "api.thingspeak.com";


// http://thingspeak.com for Channel setup
// http://freeboard.io for simple dashboard from data posted
// http://arduino-tweet.appspot.com/oauth/twitter/login Get Your Twitter API Key here



void tweet(char msg[]){ 
  // Do something with the response......ignored here......cast and leave it to ripple...
  if (twitter.post(msg)) {
    int status = twitter.wait();
    if (status == 200) {
    } else {
    }
  } else {
  }
}



void setup() {
  Serial.begin(115200);
  Serial.println("I2C init");
  Wire.begin();
  Serial.println("I2C init done");
  // Initialize MPU6050
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
    Serial.println("Found a valid MPU6050 sensor"); 
    // Enable bypass mode
  mpu.setI2CMasterModeEnabled(false);
  mpu.setI2CBypassEnabled(true);
  mpu.setSleepEnabled(false);
    WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Print the IP address
  Serial.println(WiFi.localIP()); 
  // Start the server
  server.begin();
  ulMeasDelta_ms = ( (unsigned long) loop_timer * 1000);  // Sample Interval X in Seconds placed above in the declarations....
  ulNextMeas_ms = millis()+ulMeasDelta_ms;
  Serial.println("Server started");
    if (pressure.begin())
       {
  Serial.println("Initialized BMP180");
       }
       else
  {
    // Oops, something went wrong, this is usually a connection problem,
    // see the comments at the top of this sketch for the proper connections.

    Serial.println("BMP180 init fail (disconnected?)\n\n");
    while(1); // Pause forever.
  }
   baseline = getPressure();
  // Initialize HMC5883L
  Serial.println("Initialize HMC5883L");
  while (!compass.begin())
  {
    Serial.println("Could not find a valid HMC5883L sensor, check wiring!");
    delay(500);
  }
 
  // Set measurement range
  // +/- 0.88 Ga: HMC5883L_RANGE_0_88GA
  // +/- 1.30 Ga: HMC5883L_RANGE_1_3GA (default)
  // +/- 1.90 Ga: HMC5883L_RANGE_1_9GA
  // +/- 2.50 Ga: HMC5883L_RANGE_2_5GA
  // +/- 4.00 Ga: HMC5883L_RANGE_4GA
  // +/- 4.70 Ga: HMC5883L_RANGE_4_7GA
  // +/- 5.60 Ga: HMC5883L_RANGE_5_6GA
  // +/- 8.10 Ga: HMC5883L_RANGE_8_1GA
  compass.setRange(HMC5883L_RANGE_1_3GA);

  // Set measurement mode
  // Idle mode:              HMC5883L_IDLE
  // Single-Measurement:     HMC5883L_SINGLE
  // Continuous-Measurement: HMC5883L_CONTINOUS (default)
  compass.setMeasurementMode(HMC5883L_CONTINOUS);
 
  // Set data rate
  //  0.75Hz: HMC5883L_DATARATE_0_75HZ
  //  1.50Hz: HMC5883L_DATARATE_1_5HZ
  //  3.00Hz: HMC5883L_DATARATE_3HZ
  //  7.50Hz: HMC5883L_DATARATE_7_50HZ
  // 15.00Hz: HMC5883L_DATARATE_15HZ (default)
  // 30.00Hz: HMC5883L_DATARATE_30HZ
  // 75.00Hz: HMC5883L_DATARATE_75HZ
  compass.setDataRate(HMC5883L_DATARATE_3HZ);

  // Set number of samples averaged
  // 1 sample:  HMC5883L_SAMPLES_1 (default)
  // 2 samples: HMC5883L_SAMPLES_2
  // 4 samples: HMC5883L_SAMPLES_4
  // 8 samples: HMC5883L_SAMPLES_8
  compass.setSamples(HMC5883L_SAMPLES_8);
 
 
  // Set calibration offset. See HMC5883L_calibration.ino
  compass.setOffset(-56, -156);

}


double getPressure()
{
  char status;
  double T,P,p0,a;

  // You must first get a temperature measurement to perform a pressure reading.
 
  // Start a temperature measurement:
  // If request is successful, the number of ms to wait is returned.
  // If request is unsuccessful, 0 is returned.

  status = pressure.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:

    delay(status);

    // Retrieve the completed temperature measurement:
    // Note that the measurement is stored in the variable T.
    // Use '&T' to provide the address of T to the function.
    // Function returns 1 if successful, 0 if failure.

    status = pressure.getTemperature(T);
    if (status != 0)
    {
      // Start a pressure measurement:
      // The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
      // If request is successful, the number of ms to wait is returned.
      // If request is unsuccessful, 0 is returned.

      status = pressure.startPressure(3);
      if (status != 0)
      {
        // Wait for the measurement to complete:
        delay(status);

        // Retrieve the completed pressure measurement:
        // Note that the measurement is stored in the variable P.
        // Use '&P' to provide the address of P.
        // Note also that the function requires the previous temperature measurement (T).
        // (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
        // Function returns 1 if successful, 0 if failure.

        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          return(P);
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");
}

void loop() {
 
  // Only post when timer match occurs................
    if (millis()>=ulNextMeas_ms)
  {   
    ulNextMeas_ms = millis()+ulMeasDelta_ms;
 long x = micros();
  Vector norm = compass.readNormalize();

  // Calculate heading
  float heading = atan2(norm.YAxis, norm.XAxis);

  // Set declination angle on your location and fix heading
  // You can find your declination on: http://magnetic-declination.com/
  // (+) Positive or (-) for negative
  // For Glasgow / Scotland declination angle is -2'59W (negative)
  // Formula: (deg + (min / 60.0)) / (180 / M_PI);
  float declinationAngle = (-2.0 + (59.0 / 60.0)) / (180 / M_PI);
  heading += declinationAngle;

  // Correct for heading < 0deg and heading > 360deg
  if (heading < 0)
  {
    heading += 2 * PI;
  }
 
  if (heading > 2 * PI)
  {
    heading -= 2 * PI;
  }

  // Convert to degrees
  float headingDegrees = heading * 180/M_PI;

  // Fix HMC5883L issue with angles
  float fixedHeadingDegrees;
 
  if (headingDegrees >= 1 && headingDegrees < 240)
  {
    fixedHeadingDegrees = map(headingDegrees, 0, 239, 0, 179);
  } else
  if (headingDegrees >= 240)
  {
    fixedHeadingDegrees = map(headingDegrees, 240, 360, 180, 360);
  }

  // Smooth angles rotation for +/- 3deg
  int smoothHeadingDegrees = round(fixedHeadingDegrees);

  if (smoothHeadingDegrees < (previousDegree + 3) && smoothHeadingDegrees > (previousDegree - 3))
  {
    smoothHeadingDegrees = previousDegree;
  }
 
  previousDegree = smoothHeadingDegrees;
   // Use WiFiClient class to create Thingspeak Post
  WiFiClient client;
  if (!client.connect(hostts, 80)) {
    return;
  }
  //Construct the post...
  String url = "/update?key=";
  url += thingspeak_key;
  url += "&field1=";
  url += fixedHeadingDegrees;
  url += "&field2=";
  url += headingDegrees;
  url += "&field3=";
  url += smoothHeadingDegrees;
  url += "&field4=";
  url += norm.XAxis; 
  url += "&field5=";
  url += norm.YAxis;
  url += "&field6=";
  url += norm.ZAxis;

delay(3000); 
// This will send the Thingspeak Post request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + hostts + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(50);
  client.stop();
     char status;
   
    P = getPressure();
    a = pressure.altitude(P,baseline);
    p0 = pressure.sealevel(P,ALTITUDE);
    pressure.getTemperature(T);
      status = pressure.startTemperature();
  if (status != 0)
  {
    // Wait for the measurement to complete:
    delay(status);

    // Retrieve the completed temperature measurement:
    // Note that the measurement is stored in the variable T.
    // Function returns 1 if successful, 0 if failure.
  }
    status = pressure.getTemperature(T); 

   // Use WiFiClient class to create Thingspeak Post to Second Channel.....
  if (!client.connect(hostts, 80)) {
    return;
  }
  //Construct the post...
  url = "/update?key=";
  url += thingspeak_key1;
  url += "&field1=";
  url += T;
  url += "&field2=";
  url += P,2;
  url += "&field3=";
  url += P*0.0295333727,2;
  url += "&field4=";
  url += a,0; 
  url += "&field5=";
  url += a*3.28084,0;


 
// This will send the Thingspeak Post request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + hostts + "\r\n" +
               "Connection: close\r\n\r\n");
  delay(50);
  client.stop();
 
   tweet_count++;
if (tweet_count==tweet_timer){
int TEint = T+0.5;
int MpressU = p0+0.5;
  sprintf(buf, "Current room Temp: %dC Air Pressure(MSLP): %dmbar, TweetNo: %d via an #ESP8266", TEint, MpressU, i );
 tweet (buf);
    i++;
   tweet_count=0;
   }
  }
}


The modified Twitter.h.....

Code: Select all/*
  Twitter.cpp - Arduino library to Post messages to Twitter using OAuth.
  Copyright (c) NeoCat 2010-2011. All right reserved.
 
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

// ver1.2 - Use <Udp.h> to support IDE 0019 or later
// ver1.3 - Support IDE 1.0

#ifndef TWITTER_H
#define TWITTER_H

#include <inttypes.h>
#include <pgmspace.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>

class Twitter
{
private:
   uint8_t parseStatus;
   int statusCode;
   const char *token;

   WiFiClient client;;

public:
   Twitter(const char *user_and_passwd);
   
   bool post(const char *msg);
   bool checkStatus(Print *debug = NULL);
   int  wait(Print *debug = NULL);
   int  status(void) { return statusCode; }
};

#endif   //TWITTER_H



The twitter feed.....
https://twitter.com/mcuautomation

The Thingspeak page......
https://thingspeak.com/channels/73449

The Device.....
Image