Skip to content

Instantly share code, notes, and snippets.

@fourseven
Created July 26, 2017 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fourseven/32e89bec24035d46835d2ff2eae299b1 to your computer and use it in GitHub Desktop.
Save fourseven/32e89bec24035d46835d2ff2eae299b1 to your computer and use it in GitHub Desktop.
Code for my temperature sensor
#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