Hardware components | ||||||
| × | 1 | ||||
![]() |
| × | 1 | |||
Software apps and online services | ||||||
![]() |
|
This project provides a very simple example of uploading data to Thingspeak at 15 second intervals from a Bosch BME280 Environmental sensor.
Pressure, temperature, humidity, altitude, RSSI and three analog channels are sent every 15 seconds to Thingspeak. The data is sent using a hardware timer that is easily reconfigured.
The code is easily modifiable if you wish to upload different channels to Thingspeak. It supports 8 channels every 10 seconds.
To create the link from particle to Thingspeak, go to the particle console. Create a Webhook on Particle and paste the code in the custom JSON area. This code will work with multiple particles. Thingspeak is able to determine the channel by the different keys. Be sure to put your unique write key from Thingspeak in your Particle code.
https://thingspeak.com/channels/183929
{
"event": "thingSpeakWrite_",
"url": "https://api.thingspeak.com/update",
"requestType": "POST",
"form": {
"api_key": "{{k}}",
"field1": "{{1}}",
"field2": "{{2}}",
"field3": "{{3}}",
"field4": "{{4}}",
"field5": "{{5}}",
"field6": "{{6}}",
"field7": "{{7}}",
"field8": "{{8}}",
"latitude": "{{a}}",
"longitude": "{{o}}",
"elevation": "{{e}}",
"status": "{{s}}"
},
"mydevices": true,
"noDefaults": true,
"location": true
}
// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_BME280/Adafruit_BME280.h"
/***************************************************************************
This is a library for the BME280 humidity, temperature & pressure sensor
Designed specifically to work with the Adafruit BME280 Breakout
----> http://www.adafruit.com/products/2650
These sensors use I2C or SPI to communicate, 2 or 4 pins are required
to interface.
Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
This file was modified by Markus Haack (https://github.com/mhaack)
in order to work with Particle Photon & Core.
***************************************************************************/
#define BME_SCK D4
#define BME_MISO D3
#define BME_MOSI D2
#define BME_CS D5
#define SEALEVELPRESSURE_HPA (1013.25)
//This Sketch measure differential pressure across the air filter in the house HVAC
/* +-----+
* +----------| USB |----------+
* | +-----+ * |
* | [ ] VIN 3V3 [ ] |
* | [ ] GND RST [ ] |
* | [ ] TX VBAT [ ] |
* | [ ] RX [S] [R] GND [ ] |
* | [ ] WKP D7 [*] |
* | [ ] DAC +-------+ D6 [*] |
* | [ ] A5 | * | D5 [*] |
* | [ ] A4 |Photon | D4 [*] |P1 PWR
* | [ ] A3 | | D3 [*] |P2 PWR
* | [ ] A2 +-------+ D2 [*] |
* P1 | [*] A1 D1 [*] |SCL BME 0x76
* P2 | [*] A0 D0 [*] |SDA BME 0x76
* | |
* \ [] [______] /
* \_______________________/
*
*
*/
/*
This sample code demonstrates the normal use of a BME280 connected to Thingspeak
*/
Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);
Timer timer(10000, checkEnvironment); // call this function every 10 seconds
Timer timer2(10000, serialDebug); // call this function every 10 seconds
Timer timer3(15000, updateThingspeak);
//global Vars
int caladdress = 0;
double bme280temp = 0;
double bme280baro = 0;
double bme280humidity = 0;
double bme280altitude = 0;
float analog1 = 0;
float analog2 = 0;
float analog3 = 0;
int count = 0;
const String key = "YOUR_KEY_HERE"; //thingspeak write key
//ApplicationWatchdog wd(5000, System.reset); //5 second application watchdog
SYSTEM_MODE(SEMI_AUTOMATIC);
ApplicationWatchdog wd(60000, System.reset);
void setup() {
Serial.begin(230400);
Serial.println(F("BME280 test"));
/*if (!bme.begin(0x76)) { //0x76 is the i2c address of the sensor
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}*/
Particle.publish("DEBUG", "starting...");
if (bme.begin(0x76)) { //0x76 is the i2c address of the sensor
Particle.publish("DEBUG", "starting the environment timer...");
timer.start(); //initialize timer
timer2.start();//initialize timer2
timer3.start();//initialize timer2
}
else {
Particle.publish("WARN", "Could not find a valid BMP280 sensor, check wiring!");
}
Particle.publish("DEBUG", "started!");
Particle.connect();
Particle.variable("bme280temp", bme280temp);
Particle.variable("bme280hum", bme280humidity);
Particle.variable("bme280bar", bme280baro);
Particle.variable("bme280alt", bme280altitude);
}
void loop() {
digitalWrite(D7,!digitalRead(D7)); //blink D7
wd.checkin(); //watchdog checkin
if (System.buttonPushed() > 2000) { //trigger a wifi disconnect if you hold for over 2 seconds.
//RGB.color(255, 255, 0); // YELLOW
if (Particle.connected() == false) { //if not connected, delay, 5000ms before attempting reconnect. without delay was causing gps to fail.
Serial.println("Connecting to wifi");
Particle.connect();
delay(1000);
} else {
//Particle.disconnect();
WiFi.off();
delay(1000);
}
}
analog1 = analogRead(A0);
analog2 = analogRead(A1);
analog3 = analogRead(A2);
}
void serialDebug() {
Serial.print("Temperature = ");
Serial.print(bme.readTemperature());
Serial.println(" *C");
Serial.print("Pressure = ");
Serial.print(bme.readPressure() / 100.0F);
Serial.println(" hPa");
Serial.print("Approx. Altitude = ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.print("Humidity = ");
Serial.print(bme.readHumidity());
Serial.println(" %");
Serial.println();
}
void checkEnvironment() {
Particle.publish("RSSI", String(WiFi.RSSI()));
//Particle.publish("DEBUG", "checking the environment...");
//read sensor
bme280temp = cToF(bme.readTemperature());
bme280baro = pToHg(bme.readPressure());
bme280altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
bme280humidity = bme.readHumidity();
//publish data
//commented out to not overload particle publish. only 4 allowed in a burst
//Particle.publish("environment/temperature2", String(bme280temp));
//Particle.publish("environment/pressure2", String(bme280baro));
//Particle.publish("environment/altitude2", String(bme280altitude));
//Particle.publish("environment/humidity2", String(bme280humidity));
}
float cToF(float c) {
return c * 9/5 + 32;
}
float pToHg(float p) {
return p/3389.39;
}
/*******************************************************************************
* Function Name : updateThingspeak
* Description : sends variables to ts
* Input : doorstatus global variables
* Output : sends data to ts
* Return : void
*******************************************************************************/
bool updateThingspeak()
{
//delay (2000);
count++;
Serial.print("Updating Thingspeak:");
Serial.print(count);
int rssival = WiFi.RSSI();
//sprintf(publishString,"%d",rssival);
//bool success = Particle.publish("RSSI",publishString);
//sprintf(publishString, "%1.4f", checkbattery());
bool success = Particle.publish("thingSpeakWrite_All", +
"{ \"1\": \"" + String(rssival) + "\"," +
"\"2\": \"" + String(bme280temp) + "\"," +
"\"3\": \"" + String(bme280humidity) + "\"," +
"\"4\": \"" + String(bme280baro) + "\"," +
"\"5\": \"" + String(bme280altitude) + "\"," +
"\"6\": \"" + String(analog1) + "\"," +
"\"7\": \"" + String(analog2) + "\"," +
"\"8\": \"" + String(analog3) + "\"," +
"\"k\": \"" + key + "\" }", 60, PRIVATE);
return success; //if sent, then turn of the send flag, otherwise let it try again.
}
Comments