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...
/* 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.....
/*
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.....