├── README.md ├── doc └── circuit_diagram.jpg ├── lib └── devconf │ └── devconf.h ├── platformio.ini └── src └── main.ino /README.md: -------------------------------------------------------------------------------- 1 | # basic_sensor_node 2 | ESP8266 Sensor Node (DHT11, TSL2561, PIR) 3 | 4 | ## Getting Started 5 | 6 | The recommended way is to use the platformio for compiling and uploading this project to the ESP8266. However, if you insist on using the Arduino IDE, do rename the files so that Arduino is able to compile it. 7 | 8 | ### Prerequisites 9 | 10 | You're need to have the basic libraries installed 11 | * ESP8266 core for Arduino (automatically installed if using PlatformIO) 12 | * DHT11 13 | * Adafruit's TSL2561 https://github.com/adafruit/TSL2561-Arduino-Library 14 | 15 | 16 | ### Circuit Diagram 17 | 18 | ![Alt text](/doc/circuit_diagram.jpg?raw=true) 19 | -------------------------------------------------------------------------------- /doc/circuit_diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calvinboey/esp8266_basic_sensor_node/0f374ceb9b19c6f70966a8294adbe2a6c16cb4ee/doc/circuit_diagram.jpg -------------------------------------------------------------------------------- /lib/devconf/devconf.h: -------------------------------------------------------------------------------- 1 | 2 | const char* ssid = "ssid_here"; 3 | const char* password = "wifi_pass"; 4 | const char* mqtt_server = "test.mosquitto.org"; //address of MQTT server 5 | const int mqtt_port = 1883; //port of MQTT server 6 | 7 | const char* device_id = "topic/subtopic/sensornode"; //topic prefix 8 | char mqtt_client_id [30]; 9 | const long reconnectTimeout = 3000; //in millisecond 10 | const long sensorColTimeout = 10000; //in millisecond 11 | 12 | char message [25]; 13 | char topic [50]; 14 | 15 | const int OUT_LED = 2; //Built-in LED 16 | const int IN_PIR = 13; //PIR Sensor (Digital) 17 | const int INOUT_DHT = 12; //DHT11 temp & humidity 18 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; http://docs.platformio.org/page/projectconf.html 10 | 11 | [env:nodemcu] 12 | platform = espressif8266 13 | framework = arduino 14 | board = nodemcu 15 | # Upload via serial or OTA 16 | upload_port = /dev/cu.SLAB_USBtoUART 17 | # upload_port = 192.168.0.12 18 | -------------------------------------------------------------------------------- /src/main.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | WiFiClient espClient; 12 | PubSubClient client(espClient); 13 | DHT dht(INOUT_DHT, DHT11, 20); 14 | long now; //use by clock 15 | long just_now; //use by clock 16 | long lastReconnectAttempt = 0; 17 | long lastSensorCol = 0; 18 | int reconnectCounter = 0; 19 | char sub_topic[15]; 20 | int debug_count = 0; 21 | int pir_in; 22 | int pir_state; 23 | int pir_old_in; 24 | 25 | //Adafruit's TSL2561 Digital Lux Sensor Library 26 | Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345); 27 | 28 | void configureSensor(void) { 29 | tsl.enableAutoRange(true); 30 | tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); 31 | } 32 | 33 | boolean reconnect() { 34 | reconnectCounter++; 35 | if(reconnectCounter > 3){ 36 | Serial.println("Connection Failed! Rebooting..."); 37 | delay(300); 38 | ESP.restart(); 39 | } 40 | if (client.connect(mqtt_client_id)) { 41 | Serial.println("MQTT connected"); 42 | //publish the ip address on MQTT 43 | sprintf (topic, "%s/%s", device_id, "general/ipaddr/last"); 44 | //Uncomment. The toCharArray() has to be added in source file 45 | //client.publish(topic, WiFi.localIP().toCharArray()); 46 | reconnectCounter = 0; 47 | } 48 | return client.connected(); 49 | } 50 | 51 | void setup_mqtt(){ 52 | client.setServer(mqtt_server, mqtt_port); 53 | delay(300); //give it some time to process 54 | reconnect(); 55 | delay(300); //give it some time to process 56 | lastReconnectAttempt = 0; 57 | } 58 | 59 | //Setup is based on ESP8266 OTA template 60 | void setup() { 61 | Serial.begin(115200); 62 | Serial.println("Booting"); 63 | WiFi.mode(WIFI_STA); 64 | WiFi.begin(ssid, password); 65 | while (WiFi.waitForConnectResult() != WL_CONNECTED) { 66 | Serial.println("Connection Failed! Rebooting..."); 67 | delay(300); 68 | ESP.restart(); 69 | } 70 | 71 | Serial.printf("%s %d", "WiFi code: ", WiFi.status()); 72 | 73 | ArduinoOTA.onStart([]() { 74 | Serial.println("Start"); 75 | }); 76 | ArduinoOTA.onEnd([]() { 77 | Serial.println("\nEnd"); 78 | }); 79 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { 80 | Serial.printf("Progress: %u%%\r", (progress / (total / 100))); 81 | }); 82 | ArduinoOTA.onError([](ota_error_t error) { 83 | Serial.printf("Error[%u]: ", error); 84 | if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); 85 | else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); 86 | else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); 87 | else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); 88 | else if (error == OTA_END_ERROR) Serial.println("End Failed"); 89 | }); 90 | ArduinoOTA.begin(); 91 | Serial.println("Ready"); 92 | Serial.print("IP address: "); 93 | Serial.println(WiFi.localIP()); 94 | 95 | //setup MQTT 96 | randomSeed(analogRead(0)); 97 | sprintf(mqtt_client_id, "%s%d", device_id, random(99999)); 98 | setup_mqtt(); 99 | 100 | //Set the PIR pin 101 | pinMode(IN_PIR, INPUT); 102 | //Initialize DHT11 103 | dht.begin(); 104 | 105 | //setup TSL2561 Lux Sensor 106 | if(!tsl.begin()){ 107 | Serial.println("TSL2561 not detected"); 108 | return; 109 | } else { 110 | configureSensor(); 111 | } 112 | 113 | Serial.println("finish setup code..."); 114 | } 115 | 116 | void loop() { 117 | ArduinoOTA.handle(); 118 | 119 | //run the clock 120 | just_now = now; 121 | now = millis(); 122 | 123 | //MQTT connection check 124 | if (!client.connected()) { 125 | now = millis(); 126 | if (now - lastReconnectAttempt > reconnectTimeout) { 127 | lastReconnectAttempt = now; 128 | // Attempt to reconnect 129 | if (reconnect()) { 130 | lastReconnectAttempt = 0; 131 | } 132 | } 133 | } 134 | 135 | //Get PIR and update via MQTT when there's change of state 136 | pir_old_in = pir_in; 137 | pir_in = digitalRead(IN_PIR); 138 | if(pir_old_in != pir_in){ 139 | Serial.printf("motion: %d\n", pir_in); 140 | pir_state = pir_in; 141 | sprintf (topic, "%s/%s", device_id, "general/motion/last"); 142 | sprintf (message, "%d", pir_state); 143 | if (client.connected()) { client.publish(topic, message); } 144 | }else{ 145 | //Serial.printf("motion: %d\n", pir_in); 146 | pir_state = pir_in; 147 | sprintf (topic, "%s/%s", device_id, "general/motionneg/last"); 148 | sprintf (message, "%d", pir_state); 149 | // if (client.connected()) { client.publish(topic, message); } 150 | } 151 | 152 | now = millis(); 153 | if(now - lastSensorCol > sensorColTimeout) { 154 | lastSensorCol = millis(); 155 | //Get brightness (lux) 156 | sensors_event_t event; 157 | tsl.getEvent(&event); 158 | 159 | if (event.light){ 160 | int value = event.light; 161 | // Serial.println(value); 162 | sprintf (topic, "%s/%s", device_id, "general/luminosity/last"); 163 | sprintf (message, "%d", value); 164 | if (client.connected()) { client.publish(topic, message); } 165 | } else { 166 | // Serial.println("0"); 167 | sprintf (topic, "%s/%s", device_id, "general/luminosity/last"); 168 | sprintf (message, "%d", 0); 169 | if (client.connected()) { client.publish(topic, message); } 170 | } 171 | 172 | //DHT11 173 | int h = dht.readHumidity(); 174 | int f = dht.readTemperature(false); //false=celcius 175 | if (isnan(h) || isnan(f)) { 176 | return; 177 | } 178 | Serial.printf("humidity: %d\n", h); 179 | Serial.printf("temperature: %d\n", f); 180 | sprintf (topic, "%s/%s", device_id, "general/humidity/last"); 181 | sprintf (message, "%d", h); 182 | if (client.connected()) { client.publish(topic, message); } 183 | sprintf (topic, "%s/%s", device_id, "general/temperature/last"); 184 | sprintf (message, "%d", f); 185 | if (client.connected()) { client.publish(topic, message); } 186 | } //end of timeout portion 187 | 188 | delay(10); 189 | client.loop(); 190 | 191 | } 192 | --------------------------------------------------------------------------------