The Temperature/Sensor sensor calls to the following library
Code: Select all
/* DHT library
MIT license
written by Adafruit Industries
*/
#ifndef DHT_H
#define DHT_H
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
// Uncomment to enable printing out nice debug messages.
//#define DHT_DEBUG
// Define where debug output will be printed.
#define DEBUG_PRINTER Serial
// Setup debug printing macros.
#ifdef DHT_DEBUG
#define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); }
#define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); }
#else
#define DEBUG_PRINT(...) {}
#define DEBUG_PRINTLN(...) {}
#endif
// Define types of sensors.
#define DHT11 11
#define DHT22 22
#define DHT21 21
#define AM2301 21
class DHT {
public:
DHT(uint8_t pin, uint8_t type, uint8_t count=6);
void begin(void);
float readTemperature(bool S=false, bool force=false);
float convertCtoF(float);
float convertFtoC(float);
float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit=true);
float readHumidity(bool force=false);
boolean read(bool force=false);
private:
uint8_t data[5];
uint8_t _pin, _type;
#ifdef __AVR
// Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask
// for the digital pin connected to the DHT. Other platforms will use digitalRead.
uint8_t _bit, _port;
#endif
uint32_t _lastreadtime, _maxcycles;
bool _lastresult;
uint32_t expectPulse(bool level);
};
class InterruptLock {
public:
InterruptLock() {
noInterrupts();
}
~InterruptLock() {
interrupts();
}
};
#endif
Code: Select all
#include <Adafruit_Sensor.h>
#include <ArduinoJson.h>
#include <DHT.h>
#include <MQ2.h>
#include <hpma115S0.h>
#include <SoftwareSerial.h>
#if SIMULATED_DATA
hpma115S0.Init();
hpma115S0.StartParticleMeasurement();
void initSensor()
{
// use SIMULATED_DATA, no sensor need to be inited
}
float readTemperature()
{
return random(20, 30);
}
float readHumidity()
{
return random(30, 40);
}
#else
static DHT dht(DHT_PIN, DHT_TYPE);
static MQ2 mq2(MQ_PIN);
SoftwareSerial hpmaSerial(TX, RX);
void initSensor()
{
dht.begin();
hpmaSerial.begin();
}
int GetPM2_5()
{
return hpma115S0.GetPM2_5();
}
float readLPG()
{
return mq2.readLPG();
}
float readSmoke()
{
return mq2.readSmoke();
}
float readCO()
{
return mq2.readCO();
}
float readTemperature()
{
return dht.readTemperature();
}
float readHumidity()
{
return dht.readHumidity();
}
#endif
bool readMessage(int messageId, char *payload)
{
float smoke = readSmoke();
init _pm2_5 = GetPM2_5();
float lpg = readLPG();
float co = readCO();
float humidity = readHumidity();
float temperature = readTemperature();
StaticJsonBuffer<MESSAGE_MAX_LEN> jsonBuffer;
JsonObject &root = jsonBuffer.createObject();
root["deviceId"] = DEVICE_ID;
root["messageId"] = messageId;
bool temperatureAlert = false;
// NAN is not the valid json, change it to NULL
if (std::isnan(_pm2_5))
{
root["_pm2_5"] = NULL;
}
else
{
root["_pm2_5"] = _pm2_5;
}
if (std::isnan(smoke))
{
root["smoke"] = NULL;
}
else
{
root["smoke"] = smoke;
}
if (std::isnan(lpg))
{
root["lpg"] = NULL;
}
else
{
root["lpg"] = lpg;
}
if (std::isnan(co))
{
root["co"] = NULL;
}
else
{
root["co"] = co;
}
if (std::isnan(temperature))
{
root["temperature"] = NULL;
}
else
{
root["temperature"] = temperature;
}
if (std::isnan(humidity))
{
root["humidity"] = NULL;
}
else
{
root["humidity"] = humidity;
}
/* My modification */ root["tempAlert"] = temperatureAlert;
root.printTo(payload, MESSAGE_MAX_LEN);
return temperatureAlert;
}
void parseTwinMessage(char *message)
{
StaticJsonBuffer<MESSAGE_MAX_LEN> jsonBuffer;
JsonObject &root = jsonBuffer.parseObject(message);
if (!root.success())
{
Serial.printf("Parse %s failed.\r\n", message);
return;
}
if (root["desired"]["interval"].success())
{
interval = root["desired"]["interval"];
}
else if (root.containsKey("interval"))
{
interval = root["interval"];
}
}
the call
Code: Select all
float readTemperature()
{
return dht.readTemperature();
}
the code
Code: Select all
float humidity = readHumidity();
and the code
Code: Select all
if (std::isnan(temperature))
{
root["temperature"] = NULL;
}
else
{
root["temperature"] = temperature;
}
This is the basic functionality and it works great.
I've attached a different sensor and i'm having trouble figuring how to extract that code from it in a similar fashion because it doesn't come with any truadional library where i can easily translate it like I was able to with the DHT library
It is for the Honeywell HPMA115S0-XXX Particle Sensor
The code for simply reading the data from the unit and displaying it to a serial port is as follows
Code: Select all
/*
* Read particle matter using a Honeywell HPMA115S0-XXX and a ESP8266 (WeMos Mini)
*/
#include <SoftwareSerial.h>
#define DEBUG false
#define pin_rx D5
#define pin_tx D6
SoftwareSerial Device(pin_rx, pin_tx);
const int AutoSendOn[4] = {0x68, 0x01, 0x40, 0x57};
const int AutoSendOff[4] = {0x68, 0x01, 0x20, 0x77};
const int StartPmMeasure[4] = {0x68, 0x01, 0x01, 0x96};
const int StopPmMeasure[4] = {0x68, 0x01, 0x02, 0x95};
const int ReadPm[4] = {0x68, 0x01, 0x04, 0x93};
int isAutoSend = true;
int useReading = true;
int pm25 = 0; // PM2.5
int pm10 = 0; // PM10
unsigned long lastReading = 0;
void sendCommand(const int *cmd) {
int i;
for(i=0;i<4; i++) {
Device.write(cmd[i]);
}
// let a unicorn pass
delay(10);
}
int readResponse(int l = 32) {
int i = 0;
int buf[l];
unsigned long start = millis();
while(Device.available() > 0 && i < l) {
buf[i] = Device.read(); // read bytes from device
if(DEBUG) {
Serial.print("i: "); Serial.print(i);
Serial.print(" buf[i]: "); Serial.println(buf[i], HEX);
}
// check for HEAD or skip a byte
if(i == 0 && !(buf[0] == 0x40 || buf[0] == 0x42 || buf[0] == 0xA5 || buf[0] == 0x96)) {
if(DEBUG) { Serial.println("Skipping Byte"); }
continue;
} else {
i++;
}
if(buf[0] == 0x42 && buf[1] == 0x4d) { // Autosend
if(DEBUG) { Serial.println("Autosend"); }
l=32;
}
if(buf[0] == 0x40 && buf[2] == 0x4) { // Reading
if(DEBUG) { Serial.println("Reading"); }
l=8;
}
if(buf[0] == 0xA5 && buf[1] == 0xA5) { // Pos. ACK
if(DEBUG) { Serial.println("ACK"); }
return true;
}
if(buf[0] == 0x96 && buf[1] == 0x96) { // Neg. ACK
if(DEBUG) { Serial.println("NACK"); }
return false;
}
if (millis() - start > 1000) { // trigger Timeout after 1 sec
Serial.println("Timeout");
return false;
}
}
// check checksum in Reading
if(buf[2] == 0x04) {
// HEAD+LEN+CMD
int cs = buf[0] + buf[1] + buf[2];
int c;
// DATA
for(c = 3; c < (2 + buf[1]); c++) {
// Serial.println(buf[c]);
cs += buf[c];
}
// CS = MOD((65536-(HEAD+LEN+CMD+DATA)), 256)
cs = (65536 - cs) % 256;
// validate checksum
if(cs == buf[c]) {
// calculate PM values
pm25 = buf[3] * 256 + buf[4];
pm10 = buf[5] * 256 + buf[6];
return true;
} else {
Serial.println("Checksum mismatch");
}
} else if(buf[3] == 0x1c) { // Autoreading
int cs = 0;
int c;
// DATA
for(c = 0; c <= buf[3]; c++) {
// Serial.println(buf[c]);
cs += buf[c];
}
int checksum = buf[30] * 256 + buf[31];
if(DEBUG) {
Serial.print("Checksum: "); Serial.print(checksum, HEX);
Serial.print(" CS: "); Serial.println(cs, HEX);
}
if(cs == checksum) {
// calculate PM values
pm25 = buf[6] * 256 + buf[7];
pm10 = buf[8] * 256 + buf[9];
return true;
} else {
Serial.println("Checksum mismatch");
}
} else {
// unkown
}
return false;
}
void setup() {
// init Serial for ESP8266
Serial.begin(115200); Serial.println();
// init Serial for Device
Device.begin(9600); Device.println();
}
void loop() {
if(millis() - lastReading >= 1000 || lastReading == 0) {
lastReading = millis();
// handle AutoSend
if(isAutoSend) {
if(useReading) {
if(readResponse()) {
Serial.print("PM 2.5: "); Serial.print(pm25);
Serial.print(" / PM 10: "); Serial.println(pm10);
}
} else { // disable
Serial.println("Stop AutoSend");
sendCommand(AutoSendOff);
if(readResponse()) {
Serial.println("AutoSend disabled.");
isAutoSend = !isAutoSend;
}
}
} else {
sendCommand(ReadPm);
if(readResponse()) {
Serial.print("PM 2.5: "); Serial.print(pm25);
Serial.print(" / PM 10: "); Serial.println(pm10);
}
}
}
}
The full Azure Code is attached here https://github.com/rezivor/Multisensor