#include <WiFi.h>
#include <WebSocketsClient.h>
#include <Preferences.h>
#include "DHT.h"
#include <time.h>
#define DHTPIN 32
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
Preferences preferences;
Preferences preferencesTimer;
WebSocketsClient webSocket;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* address = "";
const uint16_t port = 24899;
const char* route = "/ws";
const int dataPin = 13;
const int clockPin = 27;
const int latchPin = 14;
const int dataPinIn = 5; /* Q7 */
const int latchPinIn = 16; /* PL */
const int clockPinIn = 17; /* CP */
const int OE_595 = 4;
int stanjeOut[8] = {0, 0, 0, 0, 0, 0, 0, 0};
const int led4 = 26;
const int input1 = 32;
const int input2 = 33;
const int input3 = 34;
const int input4 = 35;
int konektovano = 0;
uint32_t chipId = 0;
String prefiks = "";
String temp = "";
String slanje = "";
String slanjeIn = "";
String prethodnoSlanjeIn = "11111111";
String prvoSlanje = "";
const int pulseWidth = 10;
int stanjeOutLoop[8] = {0, 0, 0, 0, 0, 0, 0, 0};
int stanjeOutLoopStaro[8] = {0, 0, 0, 0, 0, 0, 0, 0};
// Struktura za čuvanje informacija o izlazu
struct OutputInfo {
unsigned long onTime;
unsigned long offTime;
};
// Niz struktura za svaki izlaz
OutputInfo outputInfos[8];
void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) {
const uint8_t* src = (const uint8_t*) mem;
Serial.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len);
for (uint32_t i = 0; i < len; i++) {
if (i % cols == 0) {
Serial.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i);
}
Serial.printf("%02X ", *src);
src++;
}
Serial.printf("\n");
}
void writeData(int dataArray[8]) {
int dataVal;
digitalWrite(latchPin, LOW);
for (int i = 7; i >= 0; i--) {
digitalWrite(clockPin, LOW);
//delay(1);
dataVal = dataArray[i];
digitalWrite(dataPin, dataVal);
//delay(1);
digitalWrite(clockPin, HIGH);
}
digitalWrite(latchPin, HIGH);
}
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
float h;
// Read temperature as Celsius (the default)
float t;
// Read temperature as Fahrenheit (isFahrenheit = true)
float f;
float hif;
// Compute heat index in Celsius (isFahreheit = false)
float hic;
char * value;
int stanje;
switch (type) {
case WStype_DISCONNECTED:
Serial.printf("[WSc] Disconnected!\n");
digitalWrite(led4, HIGH);
break;
case WStype_CONNECTED:
Serial.println("-");
Serial.printf("Connected\n"); // Sending data.\n");
digitalWrite(led4, LOW);
for (int i = 0; i < 17; i = i + 8) {
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
}
prefiks = "kontroler|";
prefiks += chipId;
prefiks += "|";
prvoSlanje = "kontroler|";
prvoSlanje += chipId;
webSocket.sendTXT(prvoSlanje);
break;
case WStype_TEXT:
Serial.printf("[WSc] get text: %s\n", payload);
value = (char*)payload;
if (strncmp(value, "010", 3) == 0) {
stanjeOut[0] = 0;
preferences.putBool("out1", LOW);
}
if (strncmp(value, "011", 3) == 0) {
stanjeOut[0] = 1;
preferences.putBool("out1", HIGH);
}
if (strncmp(value, "020", 3) == 0) {
stanjeOut[1] = 0;
preferences.putBool("out2", LOW);
}
if (strncmp(value, "021", 3) == 0) {
stanjeOut[1] = 1;
preferences.putBool("out2", HIGH);
}
if (strncmp(value, "030", 3) == 0) {
stanjeOut[2] = 0;
preferences.putBool("out3", LOW);
}
if (strncmp(value, "031", 3) == 0) {
stanjeOut[2] = 1;
preferences.putBool("out3", HIGH);
}
if (strncmp(value, "040", 3) == 0) {
stanjeOut[3] = 0;
preferences.putBool("out4", LOW);
}
if (strncmp(value, "041", 3) == 0) {
stanjeOut[3] = 1;
preferences.putBool("out4", HIGH);
}
if (strncmp(value, "050", 3) == 0) {
stanjeOut[4] = 0;
preferences.putBool("out5", LOW);
}
if (strncmp(value, "051", 3) == 0) {
stanjeOut[4] = 1;
preferences.putBool("out5", HIGH);
}
if (strncmp(value, "060", 3) == 0) {
stanjeOut[5] = 0;
preferences.putBool("out6", LOW);
}
if (strncmp(value, "061", 3) == 0) {
stanjeOut[5] = 1;
preferences.putBool("out6", HIGH);
}
if (strncmp(value, "070", 3) == 0) {
stanjeOut[6] = 0;
preferences.putBool("out7", LOW);
}
if (strncmp(value, "071", 3) == 0) {
stanjeOut[6] = 1;
preferences.putBool("out7", HIGH);
}
if (strncmp(value, "080", 3) == 0) {
stanjeOut[7] = 0;
preferences.putBool("out8", LOW);
}
if (strncmp(value, "081", 3) == 0) {
stanjeOut[7] = 1;
preferences.putBool("out8", HIGH);
}
writeData(stanjeOut);
slanje = prefiks;
for (int i = 0; i <= 7; i++) {
slanje += stanjeOut[i];
}
slanje += "|";
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
h = dht.readHumidity();
// Read temperature as Celsius (the default)
t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
}
// Compute heat index in Fahrenheit (the default)
hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius (isFahreheit = false)
hic = dht.computeHeatIndex(t, h, false);
slanje += t;
slanje += "|";
slanje += h;
slanje += "|";
Serial.print(slanje);
webSocket.sendTXT(slanje);
delay(100);
// send message to server
//webSocket.sendTXT("message here");
break;
case WStype_BIN:
Serial.printf("[WSc] get binary length: %u\n", length);
hexdump(payload, length);
// send data to server
// webSocket.sendBIN(payload, length);
break;
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
break;
}
}
void setupWebSocket() {
Serial.println("Setting up WebSocket client");
// server address, port and URL
webSocket.begin(address, port, route);
// event handler
webSocket.onEvent(webSocketEvent);
// use HTTP Basic Authorization this is optional remove if not needed
// webSocket.setAuthorization("user", "Password");
// try every 5000 again if connection has failed
webSocket.setReconnectInterval(500);
}
void setup() {
preferences.begin("gpio", false);
preferencesTimer.begin("timer_prefs", false);
outputInfos[0].onTime = getTimestamp(01, 12, 0); // Uključiti u 23:08:00
outputInfos[0].offTime = getTimestamp(03, 12, 30); // Isključiti u 07:18:32
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(dataPinIn, INPUT);
pinMode(clockPinIn, OUTPUT);
pinMode(latchPinIn, OUTPUT);
pinMode(OE_595, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(input1, INPUT);
pinMode(input2, INPUT);
pinMode(input3, INPUT);
pinMode(input4, INPUT);
digitalWrite(OE_595, LOW);
stanjeOut[0] = preferences.getBool("out1", false);
stanjeOut[1] = preferences.getBool("out2", false);
stanjeOut[2] = preferences.getBool("out3", false);
stanjeOut[3] = preferences.getBool("out4", false);
stanjeOut[4] = preferences.getBool("out5", false);
stanjeOut[5] = preferences.getBool("out6", false);
stanjeOut[6] = preferences.getBool("out7", false);
stanjeOut[7] = preferences.getBool("out8", false);
writeData(stanjeOut);
Serial.begin(115200);
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(led4, HIGH);
delay(200);
digitalWrite(led4, LOW);
Serial.print(".");
delay(200);
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(led4, HIGH);
delay(500);
setupWebSocket();
}
void loop() {
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
// Čekanje da se sinhronizuje vreme
Serial.print("Čekanje na sinhronizaciju vremena");
while (!time(nullptr)) {
Serial.print(".");
delay(1000);
}
Serial.println();
// Dobijanje trenutnog vremena i ispisivanje na serijskom monitoru
time_t now = time(nullptr);
Serial.print("Trenutno vreme: ");
Serial.println(ctime(&now));
prethodnoSlanjeIn = slanjeIn;
String tempIn = "";
digitalWrite( latchPinIn, LOW);
delayMicroseconds( pulseWidth);
digitalWrite( latchPinIn, HIGH);
for (int i = 0; i < 8; i++) {
int bit = digitalRead(dataPinIn);
if (bit == HIGH) {
tempIn += "1";
} else {
tempIn += "0";
}
digitalWrite(clockPinIn, HIGH); // Shift out the next bit
delayMicroseconds( pulseWidth);
digitalWrite(clockPinIn, LOW);
}
slanjeIn = tempIn;
if (slanjeIn != prethodnoSlanjeIn) {
Serial.println(slanjeIn);
webSocket.sendTXT(slanjeIn);
}
prethodnoSlanjeIn = slanjeIn;
unsigned long currentTime = millis(); // Trenutno vreme
// Provera za svaki izlaz
for (int i = 0; i < 8; i++) {
int n = i + 1;
if (outputInfos[i].onTime) {
Serial.println(outputInfos[i].onTime);
Serial.println(outputInfos[i].offTime);
Serial.println(currentTime);
Serial.printf("Uslo 2\n");
// Uključivanje izlaza ako je vreme uključenja manje od trenutnog vremena
if (currentTime >= outputInfos[i].onTime) {
stanjeOutLoop[i] = 1;
preferences.putBool("out" + n, HIGH);
Serial.printf("Uslo 0\n");
}
// Isključivanje izlaza ako je vreme isključenja manje od trenutnog vremena
if (currentTime >= outputInfos[i].offTime) {
stanjeOutLoop[i] = 0;
preferences.putBool("out" + n, LOW);
Serial.printf("Uslo 1\n");
}
}
stanjeOutLoop[i] = preferences.getBool("out" + n, false);
}
if (stanjeOutLoop != stanjeOutLoopStaro) {
writeData(stanjeOutLoop);
Serial.printf("Uslo 3\n");
}
stanjeOutLoopStaro[8] = stanjeOutLoop[8];
delay(500);
webSocket.loop();
}
// Funkcija za dobijanje vremenskog pečata za određeno vreme
unsigned long getTimestamp(int hour, int minute, int second) {
return hour * 3600UL + minute * 60UL + second;
}