Skip to content

Instantly share code, notes, and snippets.

@gresan-gits
Created February 3, 2020 14:23
Show Gist options
  • Save gresan-gits/eb768bf7b0798c41bec1d2a7c5c5a95b to your computer and use it in GitHub Desktop.
Save gresan-gits/eb768bf7b0798c41bec1d2a7c5c5a95b to your computer and use it in GitHub Desktop.
IOT ESP 16 Relay
//**************************************************************//
// 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