//#define MY_DEBUG
#define MY_GATEWAY_ESP8266
#define MY_NODE_ID 9
#define MY_BAUD_RATE 9600
#define MY_WIFI_SSID "xxxxx"
#define MY_WIFI_PASSWORD "xxxxxxxxxxx"
#define MY_HOSTNAME "PortInt48"
#define SKETCH_NAME "PortInt48"
#define SKETCH_VERSION "2.4"
#define SKETCH_NAME_PORT "Portão Interno"
#define SKETCH_NAME_SENS_PORT_O "Sensor Portão Aberto"
#define SKETCH_NAME_SENS_PORT_C "Sensor Portão Fechado"
#define SKETCH_NAME_INFO "Estado do Portão"
//#define SKETCH_NAME_BOTAO "Botão Portão Ext"
#define MY_IP_ADDRESS 10,0,1,48
#define MY_IP_GATEWAY_ADDRESS 10,0,1,1
#define MY_IP_SUBNET_ADDRESS 255,255,255,0
#define MY_PORT 5003
#define MY_GATEWAY_MAX_CLIENTS 3
//#define MY_INCLUSION_MODE_FEATURE
//#define MY_INCLUSION_MODE_DURATION 60
//#define MY_INCLUSION_MODE_BUTTON_PIN 5 // D1
#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <ESP8266WiFi.h>
#include <SPI.h>
#include <ArduinoOTA.h>
#include <MySensors.h>
#include <NewPing.h>
#define CHILD_PORTAO_INT 1
#define CHILD_ID_SENSOR_A 2
#define CHILD_ID_SENSOR_TA 3
#define CHILD_ID_TEXT 4
#define RELE_PIN 13 //d7
#define ECHO_PIN 14 //d5
#define TRIGGER_PIN 12 //d6
#define CLOSED 0
#define OPEN 1
#define CLOSING 2
#define OPENING 3
#define MAX_DISTANCE 160
#define RELE_OFF 1
#define RELE_ON 0
int reverso = 3000;
int lastDist = 0;
int AverageDist = 0;
int cState = 0;
int lState = 0;
int lLimit = 0;
int Distx = 0;
int lDistx = 0;
int incomingBlindData = 0;
int distmin = 13;
int distmax = 80;
int Level_FECHADO = 2;
int Level_ABERTO = 2;
int Level_CONTROLE = 23 ;
int lastState = 0;
int lastposition = 0;
int aberto = 0;
int abertototal = 0;
boolean metric = true;
boolean obstruction = false;
const char *currentState[] = { "Fechado", "Aberto", "Fechando", "Abrindo" };
static int status = 0; // 0=cover is down, 1=cover is up
static bool initial_state_sent = false;
unsigned long lastsend = 0;
unsigned long lastsendx = 0;
enum State {STOP, UP, DOWN,};
static int State = STOP;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
MyMessage msg_Porcent(CHILD_PORTAO_INT, V_PERCENTAGE);
MyMessage msg_S_COVER_U(CHILD_PORTAO_INT, V_UP);
MyMessage msg_S_COVER_D(CHILD_PORTAO_INT, V_DOWN);
MyMessage msg_S_COVER_S(CHILD_PORTAO_INT, V_STOP);
MyMessage msg_Aberto(CHILD_ID_SENSOR_A, V_TRIPPED);
MyMessage msg_Aberto_Total(CHILD_ID_SENSOR_TA, V_TRIPPED);
MyMessage msg_Text(CHILD_ID_TEXT, V_TEXT);
void presentation() {
sendSketchInfo(SKETCH_NAME, SKETCH_VERSION); // Send the sketch version information to the gateway and Controller
present(CHILD_PORTAO_INT, S_COVER, SKETCH_NAME_PORT); // Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_SENSOR_A, S_DOOR, SKETCH_NAME_SENS_PORT_O);
present(CHILD_ID_SENSOR_TA, S_DOOR, SKETCH_NAME_SENS_PORT_C);
present(CHILD_ID_TEXT, S_INFO, SKETCH_NAME_INFO );
metric = getControllerConfig().isMetric;
}
void setup() {
pinMode(RELE_PIN, OUTPUT);
digitalWrite(RELE_PIN, RELE_OFF);
//-------------------OTA----------------
ArduinoOTA.setHostname(MY_HOSTNAME);
ArduinoOTA.onStart([]() {
Serial.println("ArduinoOTA start");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nArduinoOTA end");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) {
Serial.println("Auth Failed");
} else if (error == OTA_BEGIN_ERROR) {
Serial.println("Begin Failed");
} else if (error == OTA_CONNECT_ERROR) {
Serial.println("Connect Failed");
} else if (error == OTA_RECEIVE_ERROR) {
Serial.println("Receive Failed");
} else if (error == OTA_END_ERROR) {
Serial.println("End Failed");
}
});
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle();
calcDistx();
getState();
if (initial_state_sent == false) {
sendState();
initial_state_sent = true;
}
if (millis() - lastsendx >= 20000) {
sendState();
lastsendx = millis();
}
if (lState != cState) {
if ( (cState == OPEN) || (cState == CLOSED) ) {
if (cState == OPEN) {
status = 1;
State = UP;
aberto = 1;
abertototal = 1;
}
else if (cState == CLOSED) {
status = 0;
State = DOWN;
aberto = 0;
abertototal = 0;
}
}
if (cState == CLOSING) {
status = 0;
State = STOP;
aberto = 1;
abertototal = 0;
}
else if (cState == OPENING) {
status = 0;
State = STOP;
aberto = 1;
abertototal = 0;
} else {
//send(msg_Porcent.set(Distx));
}
lState = cState;
sendState();
}
if ( digitalRead( RELE_PIN ) == 1) {
relayOff();
}
}
void relayOff() {
digitalWrite(RELE_PIN, RELE_OFF );
}
void getState() {
if (Distx >= distmax) {
cState = OPEN;
} else if (Distx <= distmin) {
cState = CLOSED;
} else if ((Distx < distmax) && (Distx > distmin)) {
if (lState == OPEN) {
cState = CLOSING;
} else {
cState = OPENING;
}
}
}
void receive(const MyMessage &message) {
if (message.isAck()) {
return;
}
incomingBlindData = atoi(message.data);
if (message.sensor == CHILD_PORTAO_INT) {
calcDistx();
if ((message.type == V_UP ) && (cState == OPENING)) {
m_up();
wait(reverso);
m_up();
wait(reverso);
m_up();
}
else if ((message.type == V_UP ) && (cState == CLOSING)) {
m_up();
}
else if ((message.type == V_UP ) && (cState == CLOSED)) {
m_up();
}
else if ((message.type == V_UP ) && (cState == OPEN)) {
}
else if ((message.type == V_DOWN) && (cState == OPEN)) {
m_up();
}
else if ((message.type == V_DOWN) && (cState == CLOSED)) {
}
else if ((message.type == V_DOWN) && (cState == CLOSING)) {
m_up();
wait(reverso);
m_up();
wait(reverso);
m_up();
}
else if ((message.type == V_DOWN) && (cState == OPENING)) {
m_up();
wait(reverso);
m_up();
}
else if (message.type == V_STOP ) {
m_up();
}
else if ((incomingBlindData == 100) && (cState != OPEN)) {
lastposition = 100;
m_up();
}
else if ((incomingBlindData == 0) && (cState != CLOSED)) {
lastposition = 0;
m_up();
}
else if ((incomingBlindData > 0) && (incomingBlindData < 100)) {
if ((cState == CLOSING) && (incomingBlindData > Distx)) {
m_up();
while (Distx >= incomingBlindData) {
calcDistx();
send(msg_Porcent.set(Distx));
}
m_up();
}
else if ((cState == OPENING) && (incomingBlindData < Distx)) {
m_up();
while (Distx <= incomingBlindData) {
calcDistx();
send(msg_Porcent.set(Distx));
}
m_up();
}
else if ((cState == OPENING) && (incomingBlindData > Distx)) {
m_up();
wait(reverso);
m_up();
wait(reverso);
// m_up();
while (Distx >= incomingBlindData) {
calcDistx();
send(msg_Porcent.set(Distx));
}
m_up();
}
else if ((cState == CLOSING) && (incomingBlindData < Distx)) {
m_up();
wait(reverso);
m_up();
wait(reverso);
//m_up();
while (Distx <= incomingBlindData) {
calcDistx();
send(msg_Porcent.set(Distx));
}
m_up();
}
else if ((cState == OPEN) && (incomingBlindData < Distx)) {
m_up();
while (Distx >= incomingBlindData) {
calcDistx();
send(msg_Porcent.set(Distx));
}
m_up();
}
else if ((cState == CLOSED) && (incomingBlindData > Distx)) {
m_up();
while (Distx <= incomingBlindData) {
calcDistx();
send(msg_Porcent.set(Distx));
}
m_up();
}
}*/
lastposition = incomingBlindData;
sendState(); // Update Vera with status of blinds (up/down)
}
}
void m_up() {
digitalWrite(RELE_PIN, RELE_ON); // Change relay state
wait(500);
digitalWrite(RELE_PIN, RELE_OFF);
exit;
}
void calcDistx() {
for (int i = 0; i < 10; ++i) {
AverageDist += metric ? sonar.ping_cm() : sonar.ping_in();;
wait(10);
}
AverageDist /= 10;
int dist = AverageDist;
// Serial.println("Ping: ");
Serial.print(dist); // Convert ping time to distance in cm and print result (0 = outside set distance range)
// Serial.println(metric ? " cm" : " in");
if (dist != lastDist) {
lastDist = dist;
int Disty = map(lastDist, distmin, distmax, 0, 100);
Distx = constrain(Disty, 0, 100);
// Serial.print("Ping CONERTIDO: ");
// Serial.print(Distx); // Convert ping time to distance in cm and print result (0 = outside set distance range)
// Serial.println(metric ? " cm" : " in");
}
}
void sendState() {
send( msg_Text.set( currentState[cState] ) );
send(msg_S_COVER_U.set(State == UP));
send(msg_S_COVER_D.set(State == DOWN));
send(msg_S_COVER_S.set(State == STOP));
send(msg_Aberto.set(aberto));
send(msg_Aberto_Total.set(abertototal));
send(msg_Porcent.set(Distx));
}