For a project I've used few accelerometers from different suppliers all based on ADXL345
1. GY-291
This module has all pins on one side, it is very sensitive ( more then others) and looks like is not calibrated at all. Price is 2.27 USD with free shipping.
2. ADXL345 module
Pins are distributed on both sides and has two pins for power on if you want to use it with 5V and one for 3.3V so it can be used with arduino or esp8266. It is well calibrated and well build. It costs more then the GY-291 with few cents but for my projects is very good. At this time the price is 2.72 USD with free shipping.
3. SparkFun
Most expensive one 17.95 USD shipping not included is well built, and calibrated. Of course for its price you can buy at least 6 modules like this one.
All the modules have the advantages of the ADXL345 chip like tap, double tap, free fall, two interrupts, range up to 16G
At the end top is 2, 3, 1.
Some code for ESP8266 to play with.
/* ADXL345
* i2c bus SDA = GPIO0; SCL = GPIO2
*
* Just a little test message. Go to http://192.168.4.1 in a web browser
* connected to this access point to see it.
* USER: admin PASSWOR: admin
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
//ADXL345
#include <Wire.h>
/* Set these to your desired credentials. */
const char *ssid = "ESPap";
const char *password = "12345678";
ESP8266WebServer server(80);
#define DEBUG true
#define Serial if(DEBUG)Serial
#define DEVICE (0x53) // Device address as specified in data sheet
float last_value = 0;
float prelast_value = 0;
int show_count = 0;
int trigger_count = 0;
float trigger_value = -5; //DEFAULT VALUE ???
float current_value = 0;
#define ADXL345_MG2G_MULTIPLIER (0.004)
#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
byte _buff[6];
char POWER_CTL = 0x2D; //Power Control Register
char DATA_FORMAT = 0x31;
char DATAX0 = 0x32; //X-Axis Data 0
char DATAX1 = 0x33; //X-Axis Data 1
//char DATAY0 = 0x34; //Y-Axis Data 0
//char DATAY1 = 0x35; //Y-Axis Data 1
//char DATAZ0 = 0x36; //Z-Axis Data 0
//char DATAZ1 = 0x37; //Z-Axis Data 1
float max_x=0;
float min_x=0;
float cal_x=0;
float x = 0;
//Check if header is present and correct
bool is_authentified(){
Serial.println("Enter is_authentified");
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
if (cookie.indexOf("ESPSESSIONID=1") != -1) {
Serial.println("Authentification Successful");
return true;
}
}
Serial.println("Authentification Failed");
return false;
}
//root page can be accessed only if authentification is ok
void handleRoot(){
Serial.println("Enter handleRoot");
String header;
if (!is_authentified())
{
String header = "HTTP/1.1 301 OK\r\nLocation: /login\r\nCache-Control: no-cache\r\n\r\n";
server.sendContent(header);
return;
}
if (server.hasArg("RESET"))
{
Serial.println("Reset max and min values");
min_x=0;
max_x=0;
String content = "<html><body><h2>ADXL Demo</h2>";
content += " <a href=\"/login\">reset</a><BR><BR>";
server.send(200, "text/html", content);
}
String content = "<html><body><h2>ADXL demo</h2>";
//<H2>hello, you successfully connected to esp8266!</H2><br>";
if (server.hasHeader("User-Agent"))
{
//content += "the user agent used is : " + server.header("User-Agent") + "<br><br>";
content += "x :" + String((int)current_value ) + " Corr(x):" + String((float)current_value - cal_x ) + " min_x:" + String((float)min_x) + " max_x:" + String((float)max_x) + "<br><br>";
content += "Trigger value:" + String((float)trigger_value) + " trigger count:" + String(trigger_count) + "<br><br>";
}
content += " <a href=\"/login?DISCONNECT=YES\">disconnect</a><BR><BR>";
content += " <a href=\"/?RESET=YES\">Reset min and max values</a><br><br>";
content += " <a href=\"/settings\">Settings</a>";
//last line
content += " </body></html>";
server.send(200, "text/html", content);
}
void handleSettings()
{
//reading
if (server.hasArg("TRIGGER"))
{
trigger_value = server.arg("TRIGGER").toInt();
return;
}
//setting
String msg = " <br><br> <a href=\"/ \">Home</a>";
String content = "<html><body><form action='/settings' method='POST'><br>";
content += "Value:<input type='number' name='TRIGGER' min='-500' max='500' placeholder='trigger value'><br>";
content += "<input type='submit' name='SUBMIT' value='Submit'></form>" + msg + "<br>";
server.send(200, "text/html", content);
}
//login page, also called for disconnect
void handleLogin(){
String msg;
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
}
if (server.hasArg("DISCONNECT")){
Serial.println("Disconnection");
String header = "HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=0\r\nLocation: /login\r\nCache-Control: no-cache\r\n\r\n";
server.sendContent(header);
return;
}
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")){
if (server.arg("USERNAME") == "admin" && server.arg("PASSWORD") == "admin" ){
String header = "HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=1\r\nLocation: /\r\nCache-Control: no-cache\r\n\r\n";
server.sendContent(header);
Serial.println("Log in Successful");
return;
}
msg = "Wrong username/password! try again.";
Serial.println("Log in Failed");
}
String content = "<html><body><form action='/login' method='POST'>To log in, please use : admin/admin<br>";
content += "User:<input type='text' name='USERNAME' placeholder='user name'><br>";
content += "Password:<input type='password' name='PASSWORD' placeholder='password'><br>";
content += "<input type='submit' name='SUBMIT' value='Submit'></form>" + msg + "<br>";
content += "You also can go <a href='/inline'>here</a></body></html>";
server.send(200, "text/html", content);
}
//no need authentification
void handleNotFound()
{
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
float readAccel()
{
Serial.print("readAccel");
uint8_t howManyBytesToRead = 6; //6 for all axes
readFrom( DATAX0, howManyBytesToRead, _buff); //read the acceleration data from the ADXL345
short x =0;
x = (((short)_buff[1]) << 8) | _buff[0];
//short y = (((short)_buff[3]) << 8) | _buff[2];
//short z = (((short)_buff[5]) << 8) | _buff[4];
Serial.println(x * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD);
return x * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
//x = x + cal_x;
//Serial.print("x: ");
//Serial.print( x*2./512 );
//Serial.print(" y: ");
//Serial.print( y*2./512 );
//Serial.print(" z: ");
//Serial.print( z*2./512 );
//Serial.print("X: "); Serial.print( x);
//Serial.println( sqrtf(x*x+y*y+z*z)*2./512 );
//getX() = read16(ADXL345_REG_DATAX0);
//x = getX() * ADXL345_MG2G_MULTIPLIER * SENSORS_GRAVITY_STANDARD;
}
void writeTo(byte address, byte val)
{
Wire.beginTransmission(DEVICE); // start transmission to device
Wire.write(address); // send register address
Wire.write(val); // send value to write
Wire.endTransmission(); // end transmission
}
// Reads num bytes starting from address register on device in to _buff array
void readFrom(byte address, int num, byte _buff[])
{
Wire.beginTransmission(DEVICE); // start transmission to device
Wire.write(address); // sends address to read from
Wire.endTransmission(); // end transmission
Wire.beginTransmission(DEVICE); // start transmission to device
Wire.requestFrom(DEVICE, num); // request 6 bytes from device
int i = 0;
while(Wire.available()) // device may send less than requested (abnormal)
{
_buff[i] = Wire.read(); // receive a byte
i++;
}
Wire.endTransmission(); // end transmission
}
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
/* You can remove the password parameter if you want the AP to be open. */
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.on("/", handleRoot);
server.on("/login", handleLogin);
server.on("/settings", handleSettings);
server.on("/inline", [](){
server.send(200, "text/plain", "this works without need of authentification");
});
server.onNotFound(handleNotFound);
//here the list of headers to be recorded
const char * headerkeys[] = {"User-Agent","Cookie"} ;
size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
//ask server to track these headers
server.collectHeaders(headerkeys, headerkeyssize );
server.begin();
Serial.println("HTTP server started");
//ADXL345
// i2c bus SDA = GPIO0; SCL = GPIO2
Wire.begin(0,2);
// Put the ADXL345 into +/- 2G range by writing the value 0x01 to the DATA_FORMAT register.
// FYI: 0x00 = 2G, 0x01 = 4G, 0x02 = 8G, 0x03 = 16G
writeTo(DATA_FORMAT, 0x00);
// Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register.
writeTo(POWER_CTL, 0x08);
int i =0;
for(i=0; i<11; i++)
{
//uint8_t howManyBytesToRead = 6;
//readFrom( DATAX0, howManyBytesToRead, _buff);
float calib_x ;//= (((short)_buff[1]) << 8) | _buff[0];
calib_x = readAccel();
//if(i==0)
// cal_x = x;
if(i>0)
cal_x = cal_x + calib_x;
Serial.println(calib_x);
delay(100);
}
cal_x = cal_x/10;
Serial.print("cal_x: ");Serial.println(cal_x);
}
void loop() {
server.handleClient();
current_value = readAccel(); // read ONLY x, for the y and x modify the readAccel function
if((current_value - cal_x) > max_x)
max_x = current_value - cal_x;
if((current_value - cal_x) < min_x)
min_x = current_value - cal_x;
Serial.print("x: ");Serial.print(current_value); Serial.print(" x(corrected): ");Serial.print(current_value - cal_x);
Serial.print(" Min:" );Serial.print(min_x); Serial.print(" Max:" ); Serial.println(max_x);
Serial.print("Trigger value:"); Serial.print(trigger_value); Serial.print(" Count:"); Serial.println(trigger_count);
delay(100); // only read every 100ms
}
For ESP32 info and projects see my ESP32 blog.
Esp8266 blog. Learn how to compile, how to work with the wireless chip esp8266. ESP-01 ESP-03, ESP-07, ESP-12, ESP201 all are here
Wednesday, December 30, 2015
Thursday, December 17, 2015
ESP8266 as IR remote control
Today I've managed to make the ESP8266 to work as IR remote control over MQTT for my TV.
Range is now only 1m, but I am planning to increase it. Next step is to update the Android app to support TV, AC etc.
To test the code the JSON can be used:
mosquitto_pub -h broker_ip -p port -t "/62/ir/command" -m "{\"device_name\":\"ESP_47106\", \"type\":\"ir\", \"value\":\"ON\"}"
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#include <IRremoteESP8266.h>
#include <Timer.h>
#define PanasonicAddress 0x4004 // Panasonic address (Pre data)
#define PanasonicPower 0x100BCBD // Panasonic Power button
#define wifi_ssid "WLAN_62"
#define wifi_password "........"
#define mqtt_server "......."
#define mqtt_user "CATA"
#define mqtt_password "CATA"
#define mqtt_port 1880
#define IR_PIN 14
#define ir_topic "/62/ir/command"
#define device_status_topic "/62/device/status"
// Callback function header
void rx_mqtt_callback(char* topic, byte* payload, unsigned int length);
#define DEBUG false
#define Serial if(DEBUG)Serial
#define DEBUG_OUTPUT Serial
IRsend irsend(IR_PIN); //an IR led is connected to GPIO pin
WiFiClient espClient;
PubSubClient client(mqtt_server, mqtt_port, rx_mqtt_callback,espClient);
Timer t;
StaticJsonBuffer<512> jsonDeviceStatus;
JsonObject& jsondeviceStatus = jsonDeviceStatus.createObject();
char dev_name[50];
char json_buffer_status[512];
char my_ip_s[16];
void setup_wifi()
{
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect(dev_name, mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void sendMQTTUpdate()
{
IPAddress my_ip_addr = WiFi.localIP();
sprintf(my_ip_s, "%d.%d.%d.%d", my_ip_addr[0],my_ip_addr[1],my_ip_addr[2],my_ip_addr[3]);
jsondeviceStatus ["device_name"] = dev_name;
jsondeviceStatus["type"] = "ir";
jsondeviceStatus["ipaddress"] = String(my_ip_s).c_str();
jsondeviceStatus["bgn"] = 3;
jsondeviceStatus["sdk"] = ESP.getSdkVersion();//"1.4.0";
jsondeviceStatus["version"] = "1";
jsondeviceStatus["uptime"] = "1";//ESP.getVcc();
jsondeviceStatus.printTo(json_buffer_status, sizeof(json_buffer_status));
client.publish(device_status_topic, json_buffer_status , false);
Serial.println(json_buffer_status);
}
void rx_mqtt_callback(char* topic, byte* payload, unsigned int length)
{
//reserve space for incomming message
StaticJsonBuffer<256> jsonRxMqttBuffer;
int i = 0;
char rxj[256];
Serial.println(dev_name); Serial.print("Topic:");Serial.println(topic);
for(i=0;i<length;i++)
{
rxj[i] = payload[i];
}
Serial.println(rxj);
JsonObject& root = jsonRxMqttBuffer.parseObject(rxj);
if (!root.success())
{
Serial.println("parseObject() failed");
return;
}
const char* device_name = root["device_name"];
const char* type = root["type"];
const char* value = root["value"];
Serial.println(device_name);
Serial.println(type); Serial.println(value);
//if( (type == "ir") && ((value == "ON") || (value == "OFF")))
//{
/* DO A SANITIZE ON THE MESSAGE AND IF IS CLEAN SEND IR*/
sendIR();
//}
Serial.println("<=rx_mqtt_callback");
return;
}
void sendIR()
{
int i = 0;
Serial.print("sendIR for 2 sec");
for(i=0;i<20; i++)
{
irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off
delay(100);
}
}
void setup()
{
delay(1000);
irsend.begin();
Serial.begin(115200);
sprintf(dev_name, "ESP_%d", ESP.getChipId());
setup_wifi();
client.setServer(mqtt_server, 1880);
client.connect(dev_name, mqtt_user, mqtt_password);
client.subscribe(ir_topic);
if (!client.connected())
{
reconnect();
}
t.every(60 * 1000 , sendMQTTUpdate);
}
void loop() {
client.loop();
t.update();
}
https://github.com/bcatalin/ESP8266-Infrared-Panasonic/
Range is now only 1m, but I am planning to increase it. Next step is to update the Android app to support TV, AC etc.
To test the code the JSON can be used:
mosquitto_pub -h broker_ip -p port -t "/62/ir/command" -m "{\"device_name\":\"ESP_47106\", \"type\":\"ir\", \"value\":\"ON\"}"
Every minute the module will report its status with a JSON over MQTT
{"device_name":"ESP_470106","type":"ir","ipaddress":"192.168.8.150","bgn":3,"sdk":"1.3.0","version":"1","uptime":"1"}
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#include <IRremoteESP8266.h>
#include <Timer.h>
#define PanasonicAddress 0x4004 // Panasonic address (Pre data)
#define PanasonicPower 0x100BCBD // Panasonic Power button
#define wifi_ssid "WLAN_62"
#define wifi_password "........"
#define mqtt_server "......."
#define mqtt_user "CATA"
#define mqtt_password "CATA"
#define mqtt_port 1880
#define IR_PIN 14
#define ir_topic "/62/ir/command"
#define device_status_topic "/62/device/status"
// Callback function header
void rx_mqtt_callback(char* topic, byte* payload, unsigned int length);
#define DEBUG false
#define Serial if(DEBUG)Serial
#define DEBUG_OUTPUT Serial
IRsend irsend(IR_PIN); //an IR led is connected to GPIO pin
WiFiClient espClient;
PubSubClient client(mqtt_server, mqtt_port, rx_mqtt_callback,espClient);
Timer t;
StaticJsonBuffer<512> jsonDeviceStatus;
JsonObject& jsondeviceStatus = jsonDeviceStatus.createObject();
char dev_name[50];
char json_buffer_status[512];
char my_ip_s[16];
void setup_wifi()
{
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect(dev_name, mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void sendMQTTUpdate()
{
IPAddress my_ip_addr = WiFi.localIP();
sprintf(my_ip_s, "%d.%d.%d.%d", my_ip_addr[0],my_ip_addr[1],my_ip_addr[2],my_ip_addr[3]);
jsondeviceStatus ["device_name"] = dev_name;
jsondeviceStatus["type"] = "ir";
jsondeviceStatus["ipaddress"] = String(my_ip_s).c_str();
jsondeviceStatus["bgn"] = 3;
jsondeviceStatus["sdk"] = ESP.getSdkVersion();//"1.4.0";
jsondeviceStatus["version"] = "1";
jsondeviceStatus["uptime"] = "1";//ESP.getVcc();
jsondeviceStatus.printTo(json_buffer_status, sizeof(json_buffer_status));
client.publish(device_status_topic, json_buffer_status , false);
Serial.println(json_buffer_status);
}
void rx_mqtt_callback(char* topic, byte* payload, unsigned int length)
{
//reserve space for incomming message
StaticJsonBuffer<256> jsonRxMqttBuffer;
int i = 0;
char rxj[256];
Serial.println(dev_name); Serial.print("Topic:");Serial.println(topic);
for(i=0;i<length;i++)
{
rxj[i] = payload[i];
}
Serial.println(rxj);
JsonObject& root = jsonRxMqttBuffer.parseObject(rxj);
if (!root.success())
{
Serial.println("parseObject() failed");
return;
}
const char* device_name = root["device_name"];
const char* type = root["type"];
const char* value = root["value"];
Serial.println(device_name);
Serial.println(type); Serial.println(value);
//if( (type == "ir") && ((value == "ON") || (value == "OFF")))
//{
/* DO A SANITIZE ON THE MESSAGE AND IF IS CLEAN SEND IR*/
sendIR();
//}
Serial.println("<=rx_mqtt_callback");
return;
}
void sendIR()
{
int i = 0;
Serial.print("sendIR for 2 sec");
for(i=0;i<20; i++)
{
irsend.sendPanasonic(PanasonicAddress,PanasonicPower); // This should turn your TV on and off
delay(100);
}
}
void setup()
{
delay(1000);
irsend.begin();
Serial.begin(115200);
sprintf(dev_name, "ESP_%d", ESP.getChipId());
setup_wifi();
client.setServer(mqtt_server, 1880);
client.connect(dev_name, mqtt_user, mqtt_password);
client.subscribe(ir_topic);
if (!client.connected())
{
reconnect();
}
t.every(60 * 1000 , sendMQTTUpdate);
}
void loop() {
client.loop();
t.update();
}
https://github.com/bcatalin/ESP8266-Infrared-Panasonic/
Wednesday, December 9, 2015
ESP01 Blue led stays on all the time
If the blue led on your ESP01 board is ON all the time, it means that you probably connected on LED to it.
In this case, LED will act as pull down and the ESP will change the boot mode ( which you didn't want to do it)
So ESP01 will need GPIO2 on HIGH level in order to boot.
In this case, LED will act as pull down and the ESP will change the boot mode ( which you didn't want to do it)
So ESP01 will need GPIO2 on HIGH level in order to boot.
Friday, November 27, 2015
DHT22 versus BMP180. The winner is ....
For my chronothermostat project I have evaluated the 5.11USD DHT22 and 2.20 USD BMP180.
I've let them work in parallel for few days and the winner is ..... BMP180.
This is a graph for BMP180.
This is a graph for DHT22.
As you can see the DHT22 had few unwanted spikes which leads to false triggers.
DHT22 has the advantage of using one pin, BMP180 is i2c so is using 2 pins, but the temperature has no spikes.
Both sensors:
I've let them work in parallel for few days and the winner is ..... BMP180.
This is a graph for BMP180.
BMP180 |
This is a graph for DHT22.
DHT22 |
As you can see the DHT22 had few unwanted spikes which leads to false triggers.
DHT22 has the advantage of using one pin, BMP180 is i2c so is using 2 pins, but the temperature has no spikes.
Both sensors:
- are reading the same temperature
- both are showing a lower value as my current chronothermostat which is responding more quickly on changing the temperature.
If you know other sensors that are more precise and are more temperature responsive, please let me know.
Tuesday, November 24, 2015
Temperature and humidity sender
For my ESP8266 chronothermostat I need a sensor to transmit temperature every two minutes ( humidity is a bonus) and to be battery operated.
Between the transmissions the ESP is in deep sleep. As a sensor I've used the DTH22 for one sensor and BMP180 for the other one.
For rapid development I've installed the Arduino IDE (1.6.5) and update it for ESP8266.
As additional libraries I've used: PubSubClient for MQTT and ArduinoJSON for JSON formatting.
Code is sending two JSON strings one for device capabilities, and one with the data.
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#include <DHT.h>
#define DHTTYPE DHT22
#define DHTPIN 5
#define wifi_ssid "................"
#define wifi_password ".................."
#define mqtt_server "................"
#define mqtt_user "............."
#define mqtt_password "..........."
#define mqtt_port "1880"
#define dth_topic "/62/dth"
#define device_status_topic "/62/device/status"
#define DEBUG false
#define Serial if(DEBUG)Serial
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266
float humidity, temp_f; // Values read from sensor
// Time to sleep (in seconds):
const int sleepTimeS = 120; //120 seconds
/********************************************************************
* FunctionName: gettemperature
* Description : Read temperature and humidity from sensor
* Values are stored in humidity and temp_f
* Parameters : None
* Returns : None
*********************************************************************/
void gettemperature()
{
int runs=0;
do {
delay(2000);
temp_f = dht.readTemperature(false);
humidity = dht.readHumidity();
if(runs > 0)
Serial.println("##Failed to read from DHT sensor! ###");
Serial.println(String(temp_f ).c_str());
Serial.println(String(humidity ).c_str());
runs++;
}
while(isnan(temp_f) && isnan(humidity));
}
/********************************************************************
* FunctionName: setup_wifi
* Description : Setup wifi network
* Parameters : None
* Returns : None
*********************************************************************/
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
/********************************************************************
* FunctionName: reconnect
* Description : Reconnect to the wifi network in case the connection
* is lost
* Parameters : None
* Returns : None
*********************************************************************/
void reconnect() {
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
// Attempt to connect
// If you do not want to use a username and password, change next line to
// if (client.connect("ESP8266Client")) {
if (client.connect("ESP8266ClientT", mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
/********************************************************************
* FunctionName: setup
* Description : SETUP function
* Parameters : None
* Returns : None
*********************************************************************/
void setup()
{
Serial.begin(115200);
char dev_name[50];
/*
Serial.println( "Booting" );
Serial.println();
Serial.printf( "Sketch size: %u\n", ESP.getSketchSize() );
Serial.printf( "Free size: %u\n", ESP.getFreeSketchSpace() );
Serial.printf( "Heap: %u\n", ESP.getFreeHeap() );
Serial.printf( "Boot Vers: %u\n", ESP.getBootVersion() );
Serial.printf( "CPU: %uMHz\n", ESP.getCpuFreqMHz() );
Serial.printf( "SDK: %s\n", ESP.getSdkVersion() );
Serial.printf( "Chip ID: %u\n", ESP.getChipId() );
Serial.printf( "Flash ID: %u\n", ESP.getFlashChipId() );
Serial.printf( "Flash Size: %u\n", ESP.getFlashChipRealSize() );
Serial.printf( "Vcc: %u\n", ESP.getVcc() );
Serial.println();
*/
char json_buffer[512];
char json_buffer_status[512];
char my_ip_s[16];
//this one is static allocation
StaticJsonBuffer<512> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
//This one is dynamic one (just for fun). Avoid this in embeded system
//Can be changed to Static one like: StaticJsonBuffer<512> jsonDeviceStatus;
DynamicJsonBuffer jsonDeviceStatus;
JsonObject& jsondeviceStatus = jsonDeviceStatus.createObject();
sprintf(dev_name, "ESP_%d", ESP.getChipId());
setup_wifi();
client.setServer(mqtt_server, 1880);
client.connect(dev_name, mqtt_user, mqtt_password);
if (!client.connected())
{
reconnect();
}
client.loop();
IPAddress my_ip_addr = WiFi.localIP();
sprintf(my_ip_s, "%d.%d.%d.%d", my_ip_addr[0],my_ip_addr[1],my_ip_addr[2],my_ip_addr[3]);
jsondeviceStatus ["device_name"] = dev_name;
jsondeviceStatus["type"] = "dth";
jsondeviceStatus["ipaddress"] = String(my_ip_s).c_str();
jsondeviceStatus["bgn"] = 3;
jsondeviceStatus["sdk"] = ESP.getSdkVersion();
jsondeviceStatus["version"] = "1";
jsondeviceStatus["uptime"] = 0;
jsondeviceStatus.printTo(json_buffer_status, sizeof(json_buffer_status));
client.publish(device_status_topic, json_buffer_status , false);
Serial.println(json_buffer_status);
gettemperature();
String hum;
hum = String(humidity ).c_str();
root["device_name"] = dev_name;
root["type"] = "dth";
root["temperature"] = String(temp_f).c_str();
root["humidity"] = hum;
root.printTo(json_buffer, sizeof(json_buffer));
client.publish(dth_topic, json_buffer , false);
Serial.println("Go to sleep!!!!");
// deepSleep time is defined in microseconds. Multiply
// seconds by 1e6
ESP.deepSleep(sleepTimeS * 1000000); //
}
/********************************************************************
* FunctionName: loop
* Description : LOOP function
* Parameters : None
* Returns : None
*********************************************************************/
void loop() {}
Between the transmissions the ESP is in deep sleep. As a sensor I've used the DTH22 for one sensor and BMP180 for the other one.
For rapid development I've installed the Arduino IDE (1.6.5) and update it for ESP8266.
As additional libraries I've used: PubSubClient for MQTT and ArduinoJSON for JSON formatting.
Code is sending two JSON strings one for device capabilities, and one with the data.
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>
#include <DHT.h>
#define DHTTYPE DHT22
#define DHTPIN 5
#define wifi_ssid "................"
#define wifi_password ".................."
#define mqtt_server "................"
#define mqtt_user "............."
#define mqtt_password "..........."
#define mqtt_port "1880"
#define dth_topic "/62/dth"
#define device_status_topic "/62/device/status"
#define DEBUG false
#define Serial if(DEBUG)Serial
WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266
float humidity, temp_f; // Values read from sensor
// Time to sleep (in seconds):
const int sleepTimeS = 120; //120 seconds
/********************************************************************
* FunctionName: gettemperature
* Description : Read temperature and humidity from sensor
* Values are stored in humidity and temp_f
* Parameters : None
* Returns : None
*********************************************************************/
{
int runs=0;
do {
delay(2000);
temp_f = dht.readTemperature(false);
humidity = dht.readHumidity();
if(runs > 0)
Serial.println("##Failed to read from DHT sensor! ###");
Serial.println(String(temp_f ).c_str());
Serial.println(String(humidity ).c_str());
runs++;
}
while(isnan(temp_f) && isnan(humidity));
}
/********************************************************************
* FunctionName: setup_wifi
* Description : Setup wifi network
* Parameters : None
* Returns : None
*********************************************************************/
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
/********************************************************************
* FunctionName: reconnect
* Description : Reconnect to the wifi network in case the connection
* is lost
* Parameters : None
* Returns : None
*********************************************************************/
void reconnect() {
// Loop until we're reconnected
while (!client.connected())
{
Serial.print("Attempting MQTT connection...");
// Attempt to connect
// If you do not want to use a username and password, change next line to
// if (client.connect("ESP8266Client")) {
if (client.connect("ESP8266ClientT", mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
/********************************************************************
* FunctionName: setup
* Description : SETUP function
* Parameters : None
* Returns : None
*********************************************************************/
void setup()
{
Serial.begin(115200);
char dev_name[50];
/*
Serial.println( "Booting" );
Serial.println();
Serial.printf( "Sketch size: %u\n", ESP.getSketchSize() );
Serial.printf( "Free size: %u\n", ESP.getFreeSketchSpace() );
Serial.printf( "Heap: %u\n", ESP.getFreeHeap() );
Serial.printf( "Boot Vers: %u\n", ESP.getBootVersion() );
Serial.printf( "CPU: %uMHz\n", ESP.getCpuFreqMHz() );
Serial.printf( "SDK: %s\n", ESP.getSdkVersion() );
Serial.printf( "Chip ID: %u\n", ESP.getChipId() );
Serial.printf( "Flash ID: %u\n", ESP.getFlashChipId() );
Serial.printf( "Flash Size: %u\n", ESP.getFlashChipRealSize() );
Serial.printf( "Vcc: %u\n", ESP.getVcc() );
Serial.println();
*/
char json_buffer[512];
char json_buffer_status[512];
char my_ip_s[16];
//this one is static allocation
StaticJsonBuffer<512> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
//This one is dynamic one (just for fun). Avoid this in embeded system
//Can be changed to Static one like: StaticJsonBuffer<512> jsonDeviceStatus;
DynamicJsonBuffer jsonDeviceStatus;
JsonObject& jsondeviceStatus = jsonDeviceStatus.createObject();
sprintf(dev_name, "ESP_%d", ESP.getChipId());
setup_wifi();
client.setServer(mqtt_server, 1880);
client.connect(dev_name, mqtt_user, mqtt_password);
if (!client.connected())
{
reconnect();
}
client.loop();
IPAddress my_ip_addr = WiFi.localIP();
sprintf(my_ip_s, "%d.%d.%d.%d", my_ip_addr[0],my_ip_addr[1],my_ip_addr[2],my_ip_addr[3]);
jsondeviceStatus ["device_name"] = dev_name;
jsondeviceStatus["type"] = "dth";
jsondeviceStatus["ipaddress"] = String(my_ip_s).c_str();
jsondeviceStatus["bgn"] = 3;
jsondeviceStatus["sdk"] = ESP.getSdkVersion();
jsondeviceStatus["version"] = "1";
jsondeviceStatus["uptime"] = 0;
jsondeviceStatus.printTo(json_buffer_status, sizeof(json_buffer_status));
client.publish(device_status_topic, json_buffer_status , false);
Serial.println(json_buffer_status);
gettemperature();
String hum;
hum = String(humidity ).c_str();
root["device_name"] = dev_name;
root["type"] = "dth";
root["temperature"] = String(temp_f).c_str();
root["humidity"] = hum;
root.printTo(json_buffer, sizeof(json_buffer));
client.publish(dth_topic, json_buffer , false);
Serial.println("Go to sleep!!!!");
// deepSleep time is defined in microseconds. Multiply
// seconds by 1e6
ESP.deepSleep(sleepTimeS * 1000000); //
}
/********************************************************************
* FunctionName: loop
* Description : LOOP function
* Parameters : None
* Returns : None
*********************************************************************/
void loop() {}
Subscribe to:
Posts (Atom)