Created
February 3, 2020 14:23
-
-
Save gresan-gits/eb768bf7b0798c41bec1d2a7c5c5a95b to your computer and use it in GitHub Desktop.
IOT ESP 16 Relay
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
//**************************************************************// | |
// Name : 16Relay control via MQTT // | |
// Author : Son Bui-Mualinhkien.vn // | |
// Date : 23 March, 2016 // | |
// Version : 1.0 // | |
// Notes : Code for using a 74HC595 Shift Register // | |
// : Change Maximum packet size on pubsubclient lib to 512 bytes | |
// : https://play.google.com/store/apps/details?id=org.ngoinhaso.app.mqtthomecontrol //App UI | |
//**************************************************************// | |
#include <ESP8266WiFi.h> | |
#include <PubSubClient.h> | |
#include <ArduinoJson.h> | |
#include <EEPROM.h> | |
#define BUILTIN_LED 2 | |
const int addr_ipsave = 3; | |
char* new_mqtt_client ; | |
const char* ssid = "TuHu"; | |
const char* password = "tuhu123456"; | |
const char* mqtt_server = "iot.eclipse.org"; | |
const char* command_topic = "easycontrol/test"; | |
const char* reply_topic = "easycontrol/test/out"; | |
const char* device1 = "16iorelay1"; | |
const char* device2 = "16iorelay2"; | |
const char* device3 = "16iorelay3"; | |
const char* device4 = "16iorelay4"; | |
const char* device5 = "16iorelay5"; | |
const char* device6 = "16iorelay6"; | |
const char* device7 = "16iorelay7"; | |
const char* device8 = "16iorelay8"; | |
const char* device9 = "16iorelay9"; | |
const char* device10 = "16iorelay10"; | |
const char* device11 = "16iorelay11"; | |
const char* device12 = "16iorelay12"; | |
const char* device13 = "16iorelay13"; | |
const char* device14 = "16iorelay14"; | |
const char* device15 = "16iorelay15"; | |
const char* device16 = "16iorelay16"; | |
WiFiClient espClient; | |
PubSubClient client(espClient); | |
// | |
WiFiServer server(80); | |
String idcodestring = String(50); | |
String statustring = String(50); | |
String overstring = String(100); | |
int ind1 = 0; | |
int ind2 = 0; | |
int pos = 0; | |
// | |
long lastMsg = 0; | |
char msg[512]; | |
int second = 0; | |
//Esp8266 config | |
//Pin connected to ST_CP of 74HC595 | |
int latchPin = 14; | |
//Pin connected to SH_CP of 74HC595 | |
int clockPin = 12; | |
////Pin connected to DS of 74HC595 | |
int dataPin = 15; | |
////Pin connected to MR of 74HC595 | |
int resetPin = 13; | |
////Pin connected to LED | |
int ledPin = 2; | |
int lastData = 0; | |
//Prototype | |
void smartconfig_wifi(); | |
void callback(char* topic, byte* payload, unsigned int length); | |
void reconnect(); | |
void processPin(String device, String data); | |
String macToStr(const uint8_t* mac); | |
void shiftOut(int myDataPin, int myClockPin, byte myDataOut); | |
void outShiftPin(int pin, int value); | |
void output(int state); | |
void outputPin(int pin, int state); | |
void processData(uint8_t * payload, size_t length); | |
// | |
void setup() { | |
EEPROM.begin(1024); | |
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output | |
pinMode(latchPin, OUTPUT); | |
pinMode(resetPin, OUTPUT); | |
pinMode(ledPin, OUTPUT); | |
digitalWrite(resetPin, 1); | |
lastData = 0xffff; | |
output(lastData); | |
Serial.begin(115200); | |
smartconfig_wifi(); | |
String clientName; | |
clientName += "Esp-"; | |
uint8_t mac[6]; | |
WiFi.macAddress(mac); | |
clientName += macToStr(mac); | |
new_mqtt_client = (char*) malloc(sizeof(char) * clientName.length() + 1); | |
clientName.toCharArray(new_mqtt_client, clientName.length() + 1); | |
client.setServer(mqtt_server, 1883); | |
client.setCallback(callback); | |
// Start the server | |
server.begin(); | |
Serial.println("Server started"); | |
} | |
void smartconfig_wifi() | |
{ | |
int state = LOW; | |
int cnt = 0; | |
pinMode(0, INPUT_PULLUP); // Initialize the BUILTIN_LED pin as an output | |
pinMode(2, OUTPUT); // Initialize the BUILTIN_LED pin as an output | |
Serial.print("Enable Smartconfig?"); | |
while (digitalRead(0) == 1) { | |
digitalWrite(2, state); | |
Serial.print("."); | |
delay(500); | |
cnt ++; | |
state = !state; | |
if (cnt > 7) break; | |
} | |
cnt = 0; | |
if (digitalRead(0) == 0) | |
{ | |
Serial.print("Yes"); | |
while (digitalRead(0) == 0); | |
WiFi.begin("wifi", "pass");//Set wrong sid or pass to enable smartconfig | |
delay(1000); | |
} | |
else Serial.print("No"); | |
WiFi.mode(WIFI_STA); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(500); | |
Serial.print("."); | |
if (cnt++ >= 10) { | |
digitalWrite(2, LOW); | |
Serial.print("Smartconfig begin..."); | |
EEPROM.write(addr_ipsave, 0);//Reset ip save | |
EEPROM.commit(); | |
WiFi.beginSmartConfig(); | |
while (1) { | |
delay(1000); | |
if (WiFi.smartConfigDone()) { | |
Serial.println("SmartConfig Success"); | |
break; | |
} | |
} | |
} | |
} | |
Serial.println(""); | |
Serial.println(""); | |
WiFi.printDiag(Serial); | |
// Print the IP address | |
Serial.print("IP:"); | |
Serial.println(WiFi.localIP()); | |
int epp_value; | |
epp_value = (int)EEPROM.read(addr_ipsave); | |
if (epp_value == 0) { | |
//Save ip to static | |
IPAddress ipLocal = WiFi.localIP(); | |
Serial.print("IP:"); | |
Serial.println(ipLocal); | |
IPAddress gatewayLocal = WiFi.gatewayIP(); | |
Serial.print("GATEWAY: "); | |
Serial.println(gatewayLocal); | |
IPAddress subnetLocal = WiFi.subnetMask(); | |
Serial.print("NETMASK: "); | |
Serial.println(subnetLocal); | |
WiFi.config(ipLocal, gatewayLocal, subnetLocal); | |
EEPROM.write(addr_ipsave, 1);//Danh dau la da luu | |
EEPROM.commit(); | |
Serial.println("IP static save"); | |
} | |
} | |
void callback(char* topic, byte* payload, unsigned int length) { | |
Serial.print("Message arrived ["); | |
Serial.print(topic); | |
Serial.print("] "); | |
for (int i = 0; i < length; i++) { | |
Serial.print((char)payload[i]); | |
} | |
Serial.println(); | |
processData(payload, length); | |
} | |
void reconnect() { | |
// Loop until we're reconnected | |
while (!client.connected()) { | |
// // Loop until we're reconnected | |
Serial.println("Attempting MQTT connection..."); | |
Serial.print("Connecting to "); | |
Serial.print(mqtt_server); | |
Serial.print(" as "); | |
Serial.println(new_mqtt_client); | |
Serial.print("Command topic:"); | |
Serial.print(command_topic); | |
Serial.print(" and Response topic:"); | |
Serial.println(reply_topic); | |
// Attempt to connect | |
if (client.connect((char*) new_mqtt_client)) { | |
Serial.println("connected"); | |
// Once connected, publish an announcement... | |
client.publish(reply_topic, "Device is online"); | |
// ... and resubscribe | |
client.subscribe(command_topic); | |
} else { | |
Serial.print("failed, rc="); | |
Serial.print(client.state()); | |
Serial.println(" try again in 5 seconds"); | |
// Wait 5 seconds before retrying | |
delay(5000); | |
} | |
} | |
} | |
void processPin(String device, String data) | |
{ | |
int value = 0; | |
int pin = 0; | |
if (data.equals("on")) value = 0; | |
else if (data.equals("off")) value = 1; | |
if (device.equals(device1)) | |
{ | |
pin = 1; | |
} | |
else if (device.equals(device2)) | |
{ | |
pin = 2; | |
} | |
else if (device.equals(device3)) | |
{ | |
pin = 3; | |
} | |
else if (device.equals(device4)) | |
{ | |
pin = 4; | |
} | |
else if (device.equals(device5)) | |
{ | |
pin = 5; | |
} | |
else if (device.equals(device6)) | |
{ | |
pin = 6; | |
} | |
else if (device.equals(device7)) | |
{ | |
pin = 7; | |
} | |
else if (device.equals(device8)) | |
{ | |
pin = 8; | |
} | |
else if (device.equals(device9)) | |
{ | |
pin = 9; | |
} | |
else if (device.equals(device10)) | |
{ | |
pin = 10; | |
} | |
else if (device.equals(device11)) | |
{ | |
pin = 11; | |
} | |
else if (device.equals(device12)) | |
{ | |
pin = 12; | |
} | |
else if (device.equals(device13)) | |
{ | |
pin = 13; | |
} | |
else if (device.equals(device14)) | |
{ | |
pin = 14; | |
} | |
else if (device.equals(device15)) | |
{ | |
pin = 15; | |
} | |
else if (device.equals(device16)) | |
{ | |
pin = 16; | |
} | |
outputPin(pin, value); | |
} | |
String macToStr(const uint8_t* mac) | |
{ | |
String result; | |
for (int i = 0; i < 6; ++i) { | |
result += String(mac[i], 16); | |
// if (i < 5) | |
// result += ':'; | |
} | |
return result; | |
} | |
void processData(uint8_t * payload, size_t length) | |
{ | |
digitalWrite(2, LOW); // sets the LED on | |
// Allocate the correct amount of memory for the payload copy | |
byte* p = (byte*)malloc(length); | |
// Copy the payload to the new buffer | |
memcpy(p, payload, length); | |
String jsonRec = String((char*)p); | |
StaticJsonBuffer<512> buf; | |
Serial.print("json: "); | |
Serial.println(jsonRec); | |
JsonObject& json = buf.parseObject((char*)jsonRec.c_str()); | |
String device = json["id_code"]; | |
Serial.print("device Code: "); | |
Serial.println(device); | |
String data = json["status"]; | |
Serial.print("data: "); | |
Serial.println(data); | |
if ((device.length() > 0) && (data.length() > 0)) processPin(device, data); | |
// Free the memory | |
free(p); | |
//Relply Topic | |
JsonObject& jsonReply = buf.createObject(); | |
jsonReply["id_code"] = device; | |
jsonReply["status"] = data; | |
Serial.print("Json Reply:"); | |
jsonReply.printTo(Serial); | |
Serial.println(""); | |
jsonReply.printTo(msg, sizeof(msg)); | |
client.publish(reply_topic, msg); | |
digitalWrite(2, HIGH); // sets the LED off | |
} | |
void outputPin(int pin, int state) | |
{ | |
digitalWrite(latchPin, 0); | |
outShiftPin(pin, state); | |
digitalWrite(latchPin, 1); | |
} | |
void output(int state) | |
{ | |
digitalWrite(latchPin, 0); | |
shiftOut(dataPin, clockPin, highByte(state)); | |
shiftOut(dataPin, clockPin, lowByte(state)); | |
digitalWrite(latchPin, 1); | |
lastData = state; | |
} | |
void outShiftPin(int pin, int value) { | |
//defines a local variable | |
int pin_h, pin_l; | |
bitWrite(lastData, pin, value); | |
pin_h = highByte(lastData); | |
pin_l = lowByte(lastData); | |
shiftOut(dataPin, clockPin, pin_h); | |
shiftOut(dataPin, clockPin, pin_l); | |
} | |
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { | |
int i = 0; | |
int pinState; | |
pinMode(myClockPin, OUTPUT); | |
pinMode(myDataPin, OUTPUT); | |
digitalWrite(myDataPin, 0); | |
digitalWrite(myClockPin, 0); | |
for (i = 7; i >= 0; i--) { | |
digitalWrite(myClockPin, 0); | |
if ( myDataOut & (1 << i) ) { | |
pinState = 1; | |
} | |
else { | |
pinState = 0; | |
} | |
//Sets the pin to HIGH or LOW depending on pinState | |
digitalWrite(myDataPin, pinState); | |
//register shifts bits on upstroke of clock pin | |
digitalWrite(myClockPin, 1); | |
//zero the data pin after shift to prevent bleed through | |
digitalWrite(myDataPin, 0); | |
} | |
//stop shifting | |
digitalWrite(myClockPin, 0); | |
} | |
void loop() { | |
if (!client.connected()) { | |
reconnect(); | |
} | |
client.loop(); | |
long now = millis(); | |
if (now - lastMsg > 1000) { | |
lastMsg = now; | |
++second; | |
snprintf (msg, 75, "Seconds Counter #%ld", second); | |
Serial.println(msg); | |
} | |
// Check if a client has connected | |
WiFiClient client = server.available(); | |
if (!client) { | |
return; | |
} | |
// Wait until the client sends some data | |
Serial.println("new client"); | |
while (!client.available()) { | |
delay(1); | |
} | |
// Read the first line of the request | |
String req = client.readStringUntil('\r'); | |
Serial.print("Request:"); | |
Serial.println(req); | |
client.flush(); | |
//GET /?id_code=abc&status=on HTTP/1.1 | |
if (req.indexOf("id_code") != -1) { | |
ind1 = req.indexOf("="); | |
ind2 = req.indexOf('&'); | |
idcodestring = req.substring(ind1 + 1, ind2); | |
Serial.println(idcodestring); | |
pos = req.length(); //capture string length | |
//capture front part of command string | |
overstring = req.substring(ind2, pos); | |
Serial.println(overstring); | |
ind1 = 0; ind2 = 0; | |
if (overstring.indexOf("status") != -1) { | |
ind1 = overstring.indexOf("="); | |
ind2 = overstring.indexOf(' '); | |
statustring = overstring.substring(ind1 + 1, ind2); | |
Serial.println(statustring); | |
} | |
String device = idcodestring; | |
Serial.print("device Code: "); | |
Serial.println(device); | |
String data = statustring; | |
if ((device.length() > 0) && (data.length() > 0)) processPin(device, data); | |
//clearing string for next read | |
idcodestring = ""; | |
statustring = ""; | |
overstring = ""; | |
// Prepare the response | |
String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n"; | |
s += "<html>\r\n"; | |
s += msg; | |
s += "</html>\n"; | |
// Send the response to the client | |
client.print(s); | |
//Reply with json | |
// client.println("HTTP/1.1 200 OK"); | |
// client.println("Content-Type: application/json;charset=utf-8"); | |
// client.println("Server: Esp8266"); | |
// client.println("Connection: close"); | |
// client.println(); | |
// client.print("{\"id_code\":\""); | |
// client.print(device); | |
// client.print("\",\"status\":\""); | |
// client.print(data); | |
// client.println("\"}"); | |
client.println(); | |
// | |
delay(1); | |
client.stop(); | |
Serial.println("Client disonnected"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment