Subir datos dun sensor THPL a Plotly
Isto vai ser un pequeno resumo de como subir datos dunha estación con sensores de temperatura, humidade, presión e luminosidade a plotly. Con isto podes facer unha gráfica coma esta: https://plot.ly/~procastino/5
Preparación:
O primeiro que tes que ter montada a túa estación de sensores, a nosa leva os seguintes compoñentes:
Cando teñas todo na mesa, a estación se configura segundo o seguinte esquema:
(Clica para ampliar)
Tamén tes que rexistrate en plotly e obter un nome de usuario e unha API Key, non é complicado, pero por se te lías tes este titorial sobre como facelo.
Librerías e código:
Para que o programa funcione, vas ter que descargar un par de librerías, a DHT para poder empregar o sensor de humidade e a de plotly para poder comunicarte cos seus servidores, aquí tes as descargas:
Cando teñas descargadas esas librerías, terás que descomprimir e colocar os dous cartafois na ubicación correspondente segundo o sistema operativo que empregues. Aquí che explican un pouco mellor o proceso.
Se xa tes as librerías instaladas, a montaxe feita e estás enchufado a internet, xa só tes que cargarlle este código tan longo e poderás comezar a ver os teus datos online. Atento aos comentarios en maiúsculas que che indican que partes do código debes cambiar, e algúns dos parámetros importantes do programa.
//collemos as librerías precisas
#include <plotly_ethernet.h>
#include <Wire.h>
#include <dht.h>
#include <SPI.h>
#include <Ethernet.h>
dht DHT;
plotly plotly; // initialize a plotly object, named plotly
int LDR=A3;
int pr;
#define DHT22_PIN 6
#define BMP085_ADDRESS 0x77 // I2C address of BMP085
const unsigned char OSS = 0; // Oversampling Setting NON SEI QUE FAI ISTO
// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
// b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
// so ...Temperature(...) must be called before ...Pressure(...).
long b5;
//initialize plotly global variables
char layout[]="{}";
char filename[] = "Sensor THPL Casa"; // NOME DO ARQUIVO DE PLOTLY. SE NON O CAMBIAMOS VAI ENGADINDO DATOS NOVOS NESTE ARQUIVO
// Ethernet Setup
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //NON IMPORTA
byte my_ip[] = { 199, 168, 222, 18 }; // google will tell you: "public ip address"
void startEthernet(){
Serial.println("Initializing ethernet");
if(Ethernet.begin(mac) == 0){
Serial.println("Failed to configure Ethernet using DHCP");
// no point in carrying on, so do nothing forevermore:
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, my_ip);
}
Serial.println("Done initializing ethernet");
delay(1000);
}
void setup()
{
Serial.begin(9600);
Wire.begin();
bmp085Calibration();
pinMode(LDR, INPUT);
startEthernet(); // initialize ethernet
// Initialize plotly settings
plotly.VERBOSE = true; // turn to false to suppress printing over serial
plotly.DRY_RUN = false; // turn to false when you want to connect to plotly's servers
plotly.username = "xxxxxxx"; // NOME DE USUARIO DE PLOTLY
plotly.api_key = "yyyyyy"; // API KEY DE PLOTLY
plotly.timestamp = true; // tell plotly that you're stamping your data with a millisecond counter and that you want plotly to convert it into a date-formatted graph
plotly.timezone = "Europe/Madrid"; // full list of timezones is here:
}
void loop()
{
//LEctura de luz
int luz=analogRead(LDR);
int l=map(luz,0,1023,0,100);
//Lectura de humidade e temperatura
int chk=DHT.read22(DHT22_PIN);
float t=DHT.temperature;
float h=DHT.humidity;
//lectura de presion
bmp085GetTemperature(bmp085ReadUT());//chamo a lectura de temperatura, formalismo
//meto este delay por se acaso da problemas a lectura
delay(2000);
pr = (bmp085GetPressure(bmp085ReadUP())/100)-900;
pr =(int) pr;
Serial.println("presion\t");
Serial.println(pr);
Serial.println("luminosidade\t");
Serial.println(l);
// Open the Stream
plotly.open_stream(1, 4, filename, layout); // plotlystream(number_of_points, number_of_traces, filename, layout)
plotly.post(millis(),pr);
delay(150);
plotly.post(millis(),t);
delay(150);
plotly.post(millis(),h);
delay(150);
plotly.post(millis(),l); // post luminosity to plotly (trace 4)
for(int i=0; i<1800; i++){ //NUMERO DE SEGUNDOS QUE AGARDAMOS ENTRE DATO E DATO (1800=MEDIA HORA)
delay(1000);
}
}
// Stores all of the bmp085's calibration values into global variables
// Calibration values are required to calculate temp and pressure
// This function should be called at the beginning of the program
void bmp085Calibration()
{
ac1 = bmp085ReadInt(0xAA);
ac2 = bmp085ReadInt(0xAC);
ac3 = bmp085ReadInt(0xAE);
ac4 = bmp085ReadInt(0xB0);
ac5 = bmp085ReadInt(0xB2);
ac6 = bmp085ReadInt(0xB4);
b1 = bmp085ReadInt(0xB6);
b2 = bmp085ReadInt(0xB8);
mb = bmp085ReadInt(0xBA);
mc = bmp085ReadInt(0xBC);
md = bmp085ReadInt(0xBE);
}
// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
{
unsigned char msb, lsb;
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(address);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 2);
while(Wire.available()<2)
;
msb = Wire.read();
lsb = Wire.read();
return (int) msb<<8 | lsb;
}
// Calculate temperature given ut.
// Value returned will be in units of 0.1 deg C
short bmp085GetTemperature(unsigned int ut)
{
long x1, x2;
x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
x2 = ((long)mc << 11)/(x1 + md);
b5 = x1 + x2;
return ((b5 + 8)>>4);
}
// Read the uncompensated temperature value
unsigned int bmp085ReadUT()
{
unsigned int ut;
// Write 0x2E into Register 0xF4
// This requests a temperature reading
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x2E);
Wire.endTransmission();
// Wait at least 4.5ms
delay(5);
// Read two bytes from registers 0xF6 and 0xF7
ut = bmp085ReadInt(0xF6);
return ut;
}
// Read the uncompensated pressure value
unsigned long bmp085ReadUP()
{
unsigned char msb, lsb, xlsb;
unsigned long up = 0;
// Write 0x34+(OSS<<6) into register 0xF4
// Request a pressure reading w/ oversampling setting
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();
// Wait for conversion, delay time dependent on OSS
delay(2 + (3<<OSS));
// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF6);
Wire.endTransmission();
Wire.requestFrom(BMP085_ADDRESS, 3);
// Wait for data to become available
while(Wire.available() < 3)
;
msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();
up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);
return up;
}
// Calculate pressure given up
// calibration values must be known
// b5 is also required so bmp085GetTemperature(...) must be called first.
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up)
{
long x1, x2, x3, b3, b6, p;
unsigned long b4, b7;
b6 = b5 - 4000;
// Calculate B3
x1 = (b2 * (b6 * b6)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
// Calculate B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
b7 = ((unsigned long)(up - b3) * (50000>>OSS));
if (b7 < 0x80000000)
p = (b7<<1)/b4;
else
p = (b7/b4)<<1;
x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>4;
return p;
}
Os teus datos en plotly:
Se todo foi ben, xa deberas ter os teus datos na web, e deberan aparecer nun ficheiriño que podes abrir desde a páxina principal, estando logueado/a. Desde plotly podes configurar moi ben a apariencia das gráficas, así como recuperar en calquera momento o histórico de datos da túa estación, o cal é moi interesante para estudar o clima do teu colexio.