2018年5月22日 星期二

DHT11 Temperature & Humidity sensor on NodeMCU using Arduino IDE


DHT11 Temperature & Humidity sensor on NodeMCU using Arduino IDE

Robo India presents tutorial on how to read temperature and humidity data through DHT11 sensor using ESP8266 wifi module on NODEMCU LUA platform.

Detailed Tutorial
1. Introduction:
The DHT11 is chosen because it is lab calibrated, accurate and stable and its signal output is digital. Most important of all, it is relatively inexpensive for the given performance. Below is the pinout of the sensor.
2. Understanding DHT11 sensor
DHT11 sensor gives humidity and temperature data. It has got following pin interface.
DHT11-Pinout_
3. Circuit
Make the following connections -
DH11-with-amica_
4. Library File
Following two libraries will be required to run this code. Download the zip file extract the same and copy this to your Arduino library folder.
This library file should be placed at the install folder of Arduino. I have a 64 bit Win7 OS and my arduino library folder address is located at
C:\Program Files (x86)\Arduino\libraries 
5. Programming
#include "DHT.h"        // including the library of DHT11 temperature and humidity sensor
#define DHTTYPE DHT11   // DHT 11

#define dht_dpin 0
DHT dht(dht_dpin, DHTTYPE); 
void setup(void)
{ 
  dht.begin();
  Serial.begin(9600);
  Serial.println("Humidity and temperature\n\n");
  delay(700);

}
void loop() {
    float h = dht.readHumidity();
    float t = dht.readTemperature();         
    Serial.print("Current humidity = ");
    Serial.print(h);
    Serial.print("%  ");
    Serial.print("temperature = ");
    Serial.print(t); 
    Serial.println("C  ");
  delay(800);
}

6. Output
Upload the above code to the NodeMCU and open serial monitor. Following output should be shown on the serial monitor.
Output
If you have any query please write us at support@roboindia.com
Thanks and Regards
Content Development Team 
Robo India
https://roboindia.com

DHT11 + NodeMcu WebServer






/*
 * Rui Santos
 * Complete Project Details http://randomnerdtutorials.com
 *
static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;
*/

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include "DHT.h"

// Uncomment one of the lines below for whatever DHT sensor type you're using!
//#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
#define DHTTYPE DHT11   // DHT 22  (AM2302), AM2321

// Replace with your network credentials
const char* ssid     = "PTS-2F";
const char* password = "";

WiFiServer server(80);

// DHT Sensor
const int DHTPin = D3;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);

// Temporary variables
static char celsiusTemp[7];
static char fahrenheitTemp[7];
static char humidityTemp[7];

// Client variables
char linebuf[80];
int charcount=0;

void setup() {
  // initialize the DHT sensor
  dht.begin();
 
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  while(!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  // attempt to connect to Wifi network:
  while(WiFi.status() != WL_CONNECTED) {
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
  server.begin();
}

void loop() {
  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    Serial.println("New client");
    memset(linebuf,0,sizeof(linebuf));
    charcount=0;
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        //read char by char HTTP request
        linebuf[charcount]=c;
        if (charcount<sizeof(linebuf)-1) charcount++;
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
            // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
            float h = dht.readHumidity();
            Serial.println(h);
            // Read temperature as Celsius (the default)
            float t = dht.readTemperature();
            Serial.println(t);
            // Read temperature as Fahrenheit (isFahrenheit = true)
            float f = dht.readTemperature(true);
            Serial.println(f);
           
            // Check if any reads failed and exit early (to try again).
            if (isnan(h) || isnan(t) || isnan(f)) {
              Serial.println("Failed to read from DHT sensor!");
              strcpy(celsiusTemp,"Failed");
              strcpy(fahrenheitTemp, "Failed");
              strcpy(humidityTemp, "Failed");       
            }
            else{
              // Computes temperature values in Celsius + Fahrenheit and Humidity
              float hic = dht.computeHeatIndex(t, h, false);     
              dtostrf(hic, 6, 2, celsiusTemp);           
              float hif = dht.computeHeatIndex(f, h);
              dtostrf(hif, 6, 2, fahrenheitTemp);       
              dtostrf(h, 6, 2, humidityTemp);
              // You can delete the following Serial.print's, it's just for debugging purposes
              /*Serial.print("Humidity: ");
              Serial.print(h);
              Serial.print(" %\t Temperature: ");
              Serial.print(t);
              Serial.print(" *C ");
              Serial.print(f);
              Serial.print(" *F\t Heat index: ");
              Serial.print(hic);
              Serial.print(" *C ");
              Serial.print(hif);
              Serial.print(" *F");
              Serial.print("Humidity: ");
              Serial.print(h);
              Serial.print(" %\t Temperature: ");
              Serial.print(t);
              Serial.print(" *C ");
              Serial.print(f);
              Serial.print(" *F\t Heat index: ");
              Serial.print(hic);
              Serial.print(" *C ");
              Serial.print(hif);
              Serial.println(" *F");*/
          }
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println();
          client.println("<!DOCTYPE HTML><html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
          client.println("<meta http-equiv=\"refresh\" content=\"30\"></head>");
          client.println("<body><div style=\"font-size: 3.5rem;\"><p>ESP32 - DHT</p><p>");
          if(atoi(celsiusTemp)>=25){
            client.println("<div style=\"color: #930000;\">");
          }
          else if(atoi(celsiusTemp)<25 && atoi(celsiusTemp)>=5){
            client.println("<div style=\"color: #006601;\">");
          }
          else if(atoi(celsiusTemp)<5){
            client.println("<div style=\"color: #009191;\">");
          }
          client.println(celsiusTemp);
          client.println("*C</p><p>");
          client.println(fahrenheitTemp);
          client.println("*F</p></div><p>");
          client.println(humidityTemp);
          client.println("%</p></div>");
          client.println("</body></html>");   
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
          memset(linebuf,0,sizeof(linebuf));
          charcount=0;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

自動連線到WiFi 後啟動WebServer



自動連線到WiFi 後啟動WebServer
















/*********
  Rui Santos
  Complete project details at http://randomnerdtutorials.com

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;
*********/

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         // https://github.com/tzapu/WiFiManager

// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Auxiliar variables to store the current output state
String output5State = "off";
String output4State = "off";

// Assign output variables to GPIO pins
const int output5 = 5;   //D1
const int output4 = 4;   //D2

void setup() {
  Serial.begin(115200);

  // Initialize the output variables as outputs
  pinMode(output5, OUTPUT);
  pinMode(output4, OUTPUT);
  // Set outputs to LOW
  digitalWrite(output5, LOW);
  digitalWrite(output4, LOW);

  // WiFiManager
  // Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  // Uncomment and run it once, if you want to erase all the stored information
  //wifiManager.resetSettings();

  // set custom ip for portal
  //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

  // fetches ssid and pass from eeprom and tries to connect
  // if it does not connect it starts an access point with the specified name
  // here  "AutoConnectAP"
  // and goes into a blocking loop awaiting configuration
  wifiManager.autoConnect("AutoConnectAP");
  // or use this for auto generated name ESP + ChipID
  //wifiManager.autoConnect();

  // if you get here you have connected to the WiFi
  Serial.println("Connected.");

  server.begin();
}

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients
  //Serial.print(".");

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
         
            // turns the GPIOs on and off
            if (header.indexOf("GET /5/on") >= 0) {
              Serial.println("GPIO 5 on");
              output5State = "on";
              digitalWrite(output5, HIGH);
            } else if (header.indexOf("GET /5/off") >= 0) {
              Serial.println("GPIO 5 off");
              output5State = "off";
              digitalWrite(output5, LOW);
            } else if (header.indexOf("GET /4/on") >= 0) {
              Serial.println("GPIO 4 on");
              output4State = "on";
              digitalWrite(output4, HIGH);
            } else if (header.indexOf("GET /4/off") >= 0) {
              Serial.println("GPIO 4 off");
              output4State = "off";
              digitalWrite(output4, LOW);
            }
         
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the on/off buttons
            // Feel free to change the background-color and font-size attributes to fit your preferences
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
            client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
            client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
            client.println(".button2 {background-color: #77878A;}</style></head>");
         
            // Web Page Heading
            client.println("<body><h1>ESP8266 Web Server</h1>");
         
            // Display current state, and ON/OFF buttons for GPIO 5
            client.println("<p>GPIO 5 - State " + output5State + "</p>");
            // If the output5State is off, it displays the ON button     
            if (output5State=="off") {
              client.println("<p><a href=\"/5/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/5/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
             
            // Display current state, and ON/OFF buttons for GPIO 4
            client.println("<p>GPIO 4 - State " + output4State + "</p>");
            // If the output4State is off, it displays the ON button     
            if (output4State=="off") {
              client.println("<p><a href=\"/4/on\"><button class=\"button\">ON</button></a></p>");
            } else {
              client.println("<p><a href=\"/4/off\"><button class=\"button button2\">OFF</button></a></p>");
            }
            client.println("</body></html>");
         
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

2018年5月21日 星期一

ESP8266 Advanced Login Security

ESP8266 Advanced Login Security

More advanced login security for your esp project, including username, password, brute force and inactivity protection.
AdvancedShowcase (no instructions)1 hour2,681
ESP8266 Advanced Login Security

Things used in this project

Hardware components

NodeMCU ESP8266 Breakout Board
NodeMCU ESP8266 Breakout Board
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Code

Arduino code

C/C++
Full arduino code, parts that are not explained are basic NodeMCU setup stuff.
#include <ESP8266WebServer.h>

//This is our login html page, contains user and pass fields that are posted to /login
const String loginPage = "<!DOCTYPE html><html><head><title>Login</title></head><body> <div id=\"login\"> <form action='/login' method='POST'> <center> <h1>Login </h1><p><input type='text' name='user' placeholder='User name'></p><p><input type='password' name='pass' placeholder='Password'></p><br><button type='submit' name='submit'>login</button></center> </form></body></html>";
//Our page if user succesfully loged in, includes timeout timer refresh and logout href
const String loginok = "<!DOCTYPE html><html><head><title>Login</title></head><body> <div> <form action='/' method='POST'> <center> <a href=\"/refresh\">Refresh</a><br><a href=\"/logoff\">Logoff</a></center> </form></body></html>";

const char* ssid     = "";
const char* password = "";

bool lock = false; //This bool is used to control device lockout 

String anchars = "abcdefghijklmnopqrstuvwxyz0123456789", username = "admin", loginPassword = "admin"; //anchars will be explained below. username will be compared with 'user' and loginPassword with 'pass' when login is done

unsigned long logincld = millis(), reqmillis = millis(), tempign = millis(); //First 2 timers are for lockout and last one is inactivity timer

uint8_t i, trycount = 0; // i is used for for index, trycount will be our buffer for remembering how many false entries there were

ESP8266WebServer server(80);

String sessioncookie; //this is cookie buffer

void setup(void){
  Serial.begin(115200);
  delay(10);

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  gencookie(); //generate new cookie on device start

  server.on("/", handleRoot);
  
  server.onNotFound(handleNotFound);
  
  server.on("/login", handleLogin);
  server.on("/refresh", refresh);
  server.on("/logoff", logoff);

  const char * headerkeys[] = {"User-Agent","Cookie"} ;
  size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
  server.collectHeaders(headerkeys, headerkeyssize ); //These 3 lines tell esp to collect User-Agent and Cookie in http header when request is made
  
  server.begin();
}


bool is_authentified(){ //This function checks for Cookie header in request, it compares variable c to sessioncookie and returns true if they are the same
  if (server.hasHeader("Cookie")){
    String cookie = server.header("Cookie"), authk = "c=" + sessioncookie;
    if (cookie.indexOf(authk) != -1) return true;
  }
  return false;
}

void handleRoot(){
  
  String header;
  if (!is_authentified()){ //This here checks if your cookie is valid in header and it redirects you to /login if not, if ok send loginok html file
    String header = "HTTP/1.1 301 OK\r\nLocation: /login\r\nCache-Control: no-cache\r\n\r\n";
    server.sendContent(header);
    return;
  }
  tempign = millis(); //reset the inactivity timer if someone logs in
  server.send(200, "text/html", loginok);
  
}

void handleLogin(){
  
  if (server.hasHeader("Cookie")){   
    String cookie = server.header("Cookie"); //Copy the Cookie header to this buffer
  }

  if (server.hasArg("user") && server.hasArg("pass")){ //if user posted with these arguments
    if (server.arg("user") == username &&  server.arg("pass") == loginPassword && !lock){ //check if login details are good and dont allow it if device is in lockdown
      String header = "HTTP/1.1 301 OK\r\nSet-Cookie: c=" + sessioncookie + "\r\nLocation: /\r\nCache-Control: no-cache\r\n\r\n"; //if above values are good, send 'Cookie' header with variable c, with format 'c=sessioncookie'
      server.sendContent(header);
      trycount = 0; //With good headers in mind, reset the trycount buffer
      return;
    }
  
  String msg; //this is our buffer that we will add to the login html page when headers are wrong or device is locked
  msg = "<center><br>";
  if (trycount != 10 && !lock)trycount++; //If system is not locked up the trycount buffer
  if (trycount < 10 && !lock){ //We go here if systems isn't locked out, we give user 10 times to make a mistake after we lock down the system, thus making brute force attack almost imposible
    msg += "Wrong username/password<p></p>";
    msg += "You have ";
    msg += (10 - trycount);
    msg += " tries before system temporarily locks out.";
    logincld = millis(); //Reset the logincld timer, since we still have available tries
  }
  
  if (trycount == 10){ //If too much bad tries
    if(lock){
      msg += "Too much invalid login requests, you can use this device in ";
      msg += 5 - ((millis() - logincld) / 60000); //Display lock time remaining in minutes
      msg += " minutes.";
    }
    else{
       logincld = millis();
       lock = true;  
       msg += "Too much invalid login requests, you can use this device in 5 minutes."; //This happens when your device first locks down
    }
     
    
  }
  }
  String content = loginPage;
  content +=  msg + "</center>";
  server.send(200, "text/html", content); //merge loginPage and msg and send it
}

void handleNotFound(){
  server.send(404, "text/plain", "Not found");
}

void gencookie(){
  sessioncookie = "";
  for( i = 0; i < 32; i++) sessioncookie += anchars[random(0, anchars.length())]; //Using randomchar from anchars string generate 32-bit cookie
}

void loop(void){
  server.handleClient();

    if(lock && abs(millis() - logincld) > 300000){
      lock = false;
      trycount = 0;
      logincld = millis(); //After 5 minutes is passed unlock the system
    }
    
    if(!lock && abs(millis() - logincld) > 60000){
      trycount = 0;
      logincld = millis();
      //After minute is passed without bad entries, reset trycount
    }
    
   
   if(abs(millis() - tempign) > 120000){
     gencookie();
     tempign = millis();
     //if there is no activity from loged on user, change the generate a new cookie. This is more secure than adding expiry to the cookie header
  } 
}

void logoff(){
  String header = "HTTP/1.1 301 OK\r\nSet-Cookie: c=0\r\nLocation: /login\r\nCache-Control: no-cache\r\n\r\n"; //Set 'c=0', it users header, effectively deleting it's header
  server.sendContent(header);
}

void refresh(){
  if(is_authentified()){ //this is for reseting the inactivity timer, it covers everything explained above
    tempign = millis();
    String header = "HTTP/1.1 301 OK\r\nLocation: /\r\nCache-Control: no-cache\r\n\r\n";
    server.sendContent(header); 
  }
  else{
    String header = "HTTP/1.1 301 OK\r\nLocation: /login\r\nCache-Control: no-cache\r\n\r\n";
    server.sendContent(header);
  }
}

Node-Red --> MQTT --> Fuxa

Node-Red --> MQTT --> Fuxa      FUXA(一個開源的 Web HMI / SCADA 自動化監控軟體)的專案設定檔 。 這份設定檔完整定義了 HMI 監控畫面的 後端通訊(MQTT 連線、點位標籤) 與 前端網頁圖形介面(SVG 畫布...