Created
July 26, 2017 21:03
-
-
Save fourseven/32e89bec24035d46835d2ff2eae299b1 to your computer and use it in GitHub Desktop.
Code for my temperature sensor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#include <Stream.h> | |
#include <ESP8266WiFi.h> | |
#include <ESP8266WiFiMulti.h> | |
// DHT22 - https://learn.adafruit.com/dht, https://github.com/adafruit/DHT-sensor-library | |
#include "DHT.h" | |
//AWS | |
#include "sha256.h" | |
#include "Utils.h" | |
#include "AWSClient2.h" | |
//WEBSockets | |
#include <Hash.h> | |
#include <WebSocketsClient.h> | |
//MQTT PAHO | |
#include <SPI.h> | |
#include <IPStack.h> | |
#include <Countdown.h> | |
#include <MQTTClient.h> | |
//AWS MQTT Websocket | |
#include "Client.h" | |
#include "AWSWebSocketClient.h" | |
#include "CircularByteBuffer.h" | |
#include <ArduinoLog.h> | |
// --------- Config ---------- // | |
//AWS IOT config, change these: | |
char wifi_ssid[] = "Internot"; | |
char wifi_password[] = "NOPE"; | |
char aws_endpoint[] = "NOPE.iot.ap-southeast-2.amazonaws.com"; | |
char aws_key[] = "NOPE"; | |
char aws_secret[] = "NOPE"; | |
char aws_region[] = "ap-southeast-2"; | |
const char* aws_topic = "$aws/things/Todd/shadow/update"; | |
int port = 443; | |
#define DHTPIN 14 | |
#define DHTTYPE DHT22 //Set for 11, 21, or 22 | |
//MQTT config | |
const int maxMQTTpackageSize = 512; | |
const int maxMQTTMessageHandlers = 1; | |
// ---------- /Config ----------// | |
DHT dht(DHTPIN, DHTTYPE); | |
ESP8266WiFiMulti WiFiMulti; | |
AWSWebSocketClient awsWSclient(1000); | |
IPStack ipstack(awsWSclient); | |
MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers> *client = NULL; | |
//# of connections | |
long connection = 0; | |
//generate random mqtt clientID | |
char* generateClientID () { | |
char* cID = new char[23](); | |
for (int i=0; i<22; i+=1) | |
cID[i]=(char)random(1, 256); | |
return cID; | |
} | |
//count messages arrived | |
int arrivedcount = 0; | |
//callback to handle mqtt messages | |
void messageArrived(MQTT::MessageData& md) | |
{ | |
MQTT::Message &message = md.message; | |
char* msg = new char[message.payloadlen+1](); | |
memcpy(msg,message.payload,message.payloadlen); | |
Log.notice("Message %d arrived: qos %s, retained %T, dup %T, packetid: %d, Payload %s\n", ++arrivedcount, message.qos, message.retained, message.dup, message.id, msg); | |
delete msg; | |
Log.notice("Sleeping"); | |
ESP.deepSleep(60e6, WAKE_NO_RFCAL); // (60 * 1000 * 1000) | |
} | |
//connects to websocket layer and mqtt layer | |
bool connect () { | |
if (client == NULL) { | |
client = new MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers>(ipstack); | |
} else { | |
// Rebuild client connection | |
if (client->isConnected()) { | |
client->disconnect(); | |
} | |
delete client; | |
client = new MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers>(ipstack); | |
} | |
//delay is not necessary... it just help us to get a "trustful" heap space value | |
delay(1000); | |
Log.trace("%d - conn: %d - (%d)\n", millis(), ++connection, ESP.getFreeHeap()); | |
int rc = ipstack.connect(aws_endpoint, port); | |
if (rc != 1) | |
{ | |
Log.error("error connection to the websocket server\n"); | |
return false; | |
} else { | |
Log.trace("websocket layer connected\n"); | |
} | |
Log.trace("MQTT connecting\n"); | |
MQTTPacket_connectData data = MQTTPacket_connectData_initializer; | |
data.MQTTVersion = 3; | |
char* clientID = generateClientID(); | |
data.clientID.cstring = clientID; | |
rc = client->connect(data); | |
delete[] clientID; | |
if (rc != 0) | |
{ | |
Log.error("error connection to MQTT server %s\n", rc); | |
return false; | |
} | |
Log.trace("MQTT connected\n"); | |
return true; | |
} | |
//subscribe to a mqtt topic | |
void subscribe() { | |
//subscribe to a topic | |
int rc = client->subscribe(aws_topic, MQTT::QOS0, messageArrived); | |
if (rc != 0) { | |
Log.trace("rc from MQTT subscribe is %s\n", rc); | |
return; | |
} | |
Log.trace("MQTT subscribed\n"); | |
} | |
void setup() { | |
Serial.begin(115200); | |
Log.begin(LOG_LEVEL_NOTICE, &Serial); | |
WiFiMulti.addAP(wifi_ssid, wifi_password); | |
while(WiFiMulti.run() != WL_CONNECTED) { | |
delay(100); | |
Log.verbose(".\n"); | |
} | |
Log.notice("connected to network %s\n", wifi_ssid); | |
//fill AWS parameters | |
awsWSclient.setAWSRegion(aws_region); | |
awsWSclient.setAWSDomain(aws_endpoint); | |
awsWSclient.setAWSKeyID(aws_key); | |
awsWSclient.setAWSSecretKey(aws_secret); | |
awsWSclient.setUseSSL(true); | |
// Set time on arduino | |
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); | |
dht.begin(); | |
} | |
void loop() { | |
//keep the mqtt up and running | |
if (awsWSclient.connected()) { | |
Log.trace("Connected in main loop, sending message\n"); | |
client->yield(); | |
// Reading temperature or humidity takes about 250 milliseconds! | |
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) | |
float f_humidity = dht.readHumidity(); | |
float f_temperature = dht.readTemperature(); | |
if (isnan(f_humidity) || isnan(f_temperature)) { | |
Log.error("Failed to read from DHT sensor!\n"); | |
delay(10000); | |
return; | |
}; | |
String humidity = String(f_humidity); | |
String temperature = String(f_temperature); | |
Log.notice("Humidity: %s %%\tTemperature: %s *C\t\n", humidity.c_str(), temperature.c_str()); | |
String values = "{\"state\":{\"reported\":{\"temperature\": " + temperature + ",\"humidity\": " + humidity + "}}}\r\n"; | |
// http://stackoverflow.com/questions/31614364/arduino-joining-string-and-char | |
const char *publish_message = values.c_str(); | |
subscribe(); | |
//publish | |
MQTT::Message message; | |
char buf[1000]; | |
strcpy(buf, publish_message); | |
message.qos = MQTT::QOS0; | |
message.retained = false; | |
message.dup = false; | |
message.payload = (void*)buf; | |
message.payloadlen = strlen(buf); | |
int rc = client->publish(aws_topic, message); | |
Log.notice("Message sent, waiting\n"); | |
} else { | |
//handle reconnection | |
Log.trace("Not connected in main loop, reconnecting\n"); | |
connect(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment