#include "WiFi.h"
#include "ArduinoJson.h"
#include "WebSocketsClient.h"
#include "SocketIOclient.h"
SocketIOclient SocketIO;
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"
#include "Adafruit_VL53L0X.h"
#include "DHT.h"
#include "EZButton.h"
#include "string"
#include "algorithm"
#include "bitmap.h"
#include "pitches.h"
int melody[] = {
REST, NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, REST, NOTE_B3, NOTE_C4, REST
};
float noteDurations[] = {
16, 4, 8, 8, 4, 4, 4, 4, 4, 0.2
};
void toUpperCase(std::string& str) {
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
}
std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
std::string alphabetWithUpper;
#define BTN_1 0
#define BTN_2 1
#define BTN_3 2
#define BTN_4 3
void ReadButtons(bool* states, int num) {
//Read all button states however you want
states[BTN_1] = !digitalRead(0);
states[BTN_2] = !digitalRead(2);
states[BTN_3] = !digitalRead(15);
states[BTN_4] = digitalRead(5);
}
EZButton _ezb(4, ReadButtons, 500, 100, 15);
#define DHTPIN 14
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define SEALEVELPRESSURE_HPA (1005)
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
Adafruit_BME280 bme;
//SOCKETIO
void socketIOEvent(socketIOmessageType_t type, uint8_t* payload, size_t length) {
switch (type) {
case sIOtype_DISCONNECT:
Serial.printf("[IOc] Disconnected!\n");
break;
case sIOtype_CONNECT:
Serial.printf("[IOc] Connected to url: %s\n", payload);
// join default namespace (no auto join in Socket.IO V3)
SocketIO.send(sIOtype_CONNECT, "/");
break;
case sIOtype_EVENT:
{
DynamicJsonDocument doc(1024);
DeserializationError error = deserializeJson(doc, payload, length);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
return;
}
String eventName = doc[0];
if (eventName == "requestData-from-esp") {
DynamicJsonDocument doc2(1024);
JsonArray array = doc2.to<JsonArray>();
array.add("getData");
JsonObject param1 = array.createNestedObject();
param1["BME280_temp"] = bme.readTemperature();
param1["BME280_humid"] = bme.readHumidity();
param1["BME280_p"] = bme.readPressure() / 100.0F;
param1["BME280_a"] = bme.readAltitude(SEALEVELPRESSURE_HPA);
param1["DHT11_temp"] = dht.readTemperature();
param1["DHT11_humid"] = dht.readHumidity();
// param1["id"] = doc[1];
String output;
serializeJson(doc2, output);
SocketIO.sendEVENT(output);
}
}
break;
case sIOtype_ACK:
Serial.printf("[IOc] get ack: %u\n", length);
break;
case sIOtype_ERROR:
Serial.printf("[IOc] get error: %u\n", length);
break;
case sIOtype_BINARY_EVENT:
Serial.printf("[IOc] get binary: %u\n", length);
break;
case sIOtype_BINARY_ACK:
Serial.printf("[IOc] get binary ack: %u\n", length);
break;
}
}
void setup() {
Serial.begin(115200);
// wait until serial port opens for native USB devices
while (!Serial) {
delay(1);
}
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Please wait!");
display.display();
delay(500);
if (!lox.begin()) {
Serial.println(F("Failed to boot VL53L0X"));
while (1)
;
}
delay(500);
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1)
;
}
delay(500);
dht.begin();
pinMode(5, INPUT);
pinMode(0, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
pinMode(15, INPUT_PULLUP);
_ezb.Subscribe(BTN_1, left_click, PRESSED);
_ezb.Subscribe(BTN_2, right_click, PRESSED);
_ezb.Subscribe(BTN_1, left_click, HOLD);
_ezb.Subscribe(BTN_2, right_click, HOLD);
_ezb.Subscribe(BTN_3, enter, PRESSED);
_ezb.Subscribe(BTN_4, working_mode, PRESSED);
WiFi.mode(WIFI_STA);
toUpperCase(alphabet);
alphabetWithUpper = "abcdefghijklmnopqrstuvwxyz" + alphabet + "1234567890,.!@#$%^&*()-=_+{}[];:<>/?\|";
SocketIO.disconnect();
SocketIO.begin("ahrixthinh.net", 81, "/socket.io/?EIO=4");
SocketIO.onEvent(socketIOEvent);
}
//button
int working_state = 0;
int sensorMode = 0;
bool display_off = false;
unsigned long mode1 = 0;
//sound
unsigned long notetime = 0;
int thisNote = 0;
bool alarm_on = false;
bool alarm_toggle = false;
void loop() {
_ezb.Loop();
SocketIO.loop();
if (working_state == 0) {
scanWifi();
scanWifi_draw();
if (display_off) {
display_off = false;
}
} else if (working_state == 1) {
if (display_off) {
display_off = false;
}
if (millis() - mode1 > 100) {
VL53L0X_RangingMeasurementData_t measure;
lox.rangingTest(&measure, false);
display.clearDisplay();
if (WiFi.status() != WL_CONNECTED) {
display.drawBitmap(112, 2, bitmap_wifi, 14, 11, WHITE);
} else {
display.drawBitmap(112, 2, bitmap_wifi_connected, 14, 9, WHITE);
}
display.setTextColor(WHITE);
if (sensorMode == 0) {
display.drawBitmap(0, 24, bitmap_bme280, 128, 40, WHITE);
display.setCursor(30, 4);
display.print("BME280");
display.setCursor(17, 27);
display.printf("%.2f", bme.readTemperature());
display.print(char(247));
display.printf("C");
display.setCursor(82, 27);
display.printf("%.2f%%", bme.readHumidity());
display.setCursor(17, 50);
display.printf("%.0fhPa", bme.readPressure() / 100.0F);
display.setCursor(82, 50);
display.printf("%.1fM", bme.readAltitude(SEALEVELPRESSURE_HPA));
} else if (sensorMode == 1) {
display.drawBitmap(0, 24, bitmap_dht11, 128, 14, WHITE);
display.setCursor(30, 4);
display.print("DHT11");
display.setCursor(17, 27);
display.printf("%.2f", dht.readTemperature());
display.print(char(247));
display.printf("C");
display.setCursor(82, 27);
display.printf("%.2f%%", dht.readHumidity());
} else {
display.setCursor(20, 4);
display.print("DS18B20 TO-92");
display.setCursor(50, 30);
display.print("RIP");
}
if (bme.readTemperature() > 45){
alarm_on = true;
}else{
alarm_on = false;
thisNote = 0;
}
// display.printf("Distance: %d mm\n\n", measure.RangeMilliMeter - 30);
// display.printf("Temperature: %.2f", bme.readTemperature());
// display.print(char(247));
// display.printf("C\n\n");
// display.printf("Temperature: %.2f", dht.readTemperature());
// display.print(char(247));
// display.printf("C\n\n");
display.display();
mode1 = millis();
}
} else if (working_state == 2) {
if (!display_off) {
display.clearDisplay();
display.display();
}
display_off = true;
} else {
connectWifi();
}
alarm();
}
void wifi_draw(int n, int i, bool color) {
if (!color) {
display.setTextColor(WHITE);
display.setCursor(1, i * 10 + 1);
display.print(WiFi.SSID(n));
} else {
display.setTextColor(BLACK);
display.setCursor(1, i * 10 + 1);
display.print(WiFi.SSID(n));
}
}
int select_position = 0;
int wifi_select = 0;
int wifi_numbers = 0;
std::string wifi_pass = "";
bool startScan = false;
void scanWifi() {
if (!startScan) {
wifi_numbers = WiFi.scanNetworks();
startScan = true;
}
}
void scanWifi_draw() {
if (wifi_numbers == 0) {
display.clearDisplay();
display.setCursor(0, 0);
display.print("No Wifi has been Found");
display.display();
} else if (wifi_numbers < 6) {
if (wifi_select > wifi_numbers) {
wifi_select = wifi_numbers - 1;
select_position = wifi_numbers - 1;
}
display.clearDisplay();
display.fillRect(0, select_position * 10, 128, 10, WHITE);
for (int i = 0; i < wifi_numbers; i++) {
wifi_draw(i, i, false);
}
wifi_draw(wifi_select, select_position, true);
display.display();
} else {
if (wifi_select > wifi_numbers) {
wifi_select = wifi_numbers - 1;
select_position = 5;
}
display.clearDisplay();
display.fillRect(0, select_position * 10, 128, 10, WHITE);
wifi_draw(wifi_select - select_position, 0, false);
wifi_draw(wifi_select - (select_position - 1), 1, false);
wifi_draw(wifi_select - (select_position - 2), 2, false);
wifi_draw(wifi_select - (select_position - 3), 3, false);
wifi_draw(wifi_select - (select_position - 4), 4, false);
wifi_draw(wifi_select - (select_position - 5), 5, false);
wifi_draw(wifi_select, select_position, true);
display.display();
}
}
int char_position = 0;
void connectWifi() {
display.clearDisplay();
display.fillRect(60, 54, 10, 10, WHITE);
display.setTextColor(WHITE);
display.setCursor(1, 1);
display.print(wifi_pass.c_str());
display.setCursor(1, 55);
display.setTextColor(WHITE);
display.print(alphabetWithUpper[(char_position - 6 < 0) ? alphabetWithUpper.length() + (char_position - 6) : char_position - 6]);
display.setCursor(11, 55);
display.print(alphabetWithUpper[(char_position - 5 < 0) ? alphabetWithUpper.length() + (char_position - 5) : char_position - 5]);
display.setCursor(21, 55);
display.print(alphabetWithUpper[(char_position - 4 < 0) ? alphabetWithUpper.length() + (char_position - 4) : char_position - 4]);
display.setCursor(31, 55);
display.print(alphabetWithUpper[(char_position - 3 < 0) ? alphabetWithUpper.length() + (char_position - 3) : char_position - 3]);
display.setCursor(41, 55);
display.print(alphabetWithUpper[(char_position - 2 < 0) ? alphabetWithUpper.length() + (char_position - 2) : char_position - 2]);
display.setCursor(51, 55);
display.print(alphabetWithUpper[(char_position - 1 < 0) ? alphabetWithUpper.length() + (char_position - 1) : char_position - 1]);
display.setCursor(61, 55);
display.setTextColor(BLACK);
display.print(alphabetWithUpper[char_position]);
display.setCursor(71, 55);
display.setTextColor(WHITE);
display.print(alphabetWithUpper[(char_position + 1 >= alphabetWithUpper.length()) ? char_position + 1 - alphabetWithUpper.length() : char_position + 1]);
display.setCursor(81, 55);
display.print(alphabetWithUpper[(char_position + 2 >= alphabetWithUpper.length()) ? char_position + 2 - alphabetWithUpper.length() : char_position + 2]);
display.setCursor(91, 55);
display.print(alphabetWithUpper[(char_position + 3 >= alphabetWithUpper.length()) ? char_position + 3 - alphabetWithUpper.length() : char_position + 3]);
display.setCursor(101, 55);
display.print(alphabetWithUpper[(char_position + 4 >= alphabetWithUpper.length()) ? char_position + 4 - alphabetWithUpper.length() : char_position + 4]);
display.setCursor(111, 55);
display.print(alphabetWithUpper[(char_position + 5 >= alphabetWithUpper.length()) ? char_position + 5 - alphabetWithUpper.length() : char_position + 5]);
display.setCursor(121, 55);
display.print(alphabetWithUpper[(char_position + 6 >= alphabetWithUpper.length()) ? char_position + 5 - alphabetWithUpper.length() : char_position + 6]);
display.display();
}
void working_mode() {
(working_state + 1 > 2) ? working_state = 0 : working_state++;
if (working_state == 0) {
startScan = false;
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Please wait!");
display.display();
}
}
void left_click() {
if (working_state == 0) {
if (wifi_select - 1 >= 0) {
wifi_select--;
if (select_position - 1 >= 0) select_position--;
}
} else if (working_state == 1) {
(sensorMode - 1 < 0) ? sensorMode = 2 : sensorMode--;
} else if (working_state == 3) {
(char_position - 1 < 0) ? char_position = alphabetWithUpper.length() - 1 : char_position--;
}
}
void right_click() {
if (working_state == 0) {
if (wifi_select + 1 <= wifi_numbers - 1) {
wifi_select++;
if (select_position + 1 <= 5) select_position++;
}
} else if (working_state == 1) {
(sensorMode + 1 > 2) ? sensorMode = 0 : sensorMode++;
} else if (working_state == 3) {
(char_position + 1 >= alphabetWithUpper.length()) ? char_position = 0 : char_position++;
}
}
void enter() {
if (working_state == 0) {
working_state = 3;
wifi_pass = "";
} else if (working_state == 3) {
if (alphabetWithUpper.substr(char_position, 1).compare("<") == 0) {
if (wifi_pass.length() > 0) wifi_pass.pop_back();
} else if (alphabetWithUpper.substr(char_position, 1).compare(">") == 0) {
WiFi.disconnect();
WiFi.begin(WiFi.SSID(wifi_select).c_str(), wifi_pass.c_str());
unsigned long startConnection = millis();
display.clearDisplay();
display.setCursor(1, 1);
display.print("Connecting");
while (WiFi.status() != WL_CONNECTED && millis() - startConnection < 10000) {
display.print(".");
display.display();
delay(100);
}
if (WiFi.status() != WL_CONNECTED) {
display.print("Failed");
} else {
display.print("Connected");
display.print(WiFi.localIP());
}
display.display();
delay(2000);
working_state = 0;
} else {
wifi_pass += alphabetWithUpper.substr(char_position, 1);
}
}
}
void alarm() {
if (alarm_on) {
if (millis() - notetime >= 1000 / noteDurations[thisNote] + 1000 / noteDurations[thisNote] * 0.2) {
(thisNote + 1 > 9) ? thisNote = 0 : thisNote++;
tone(17, melody[thisNote], 1000 / noteDurations[thisNote] + 1000 / noteDurations[thisNote] * 0.2);
notetime = millis();
}
alarm_toggle = true;
} else {
if (alarm_toggle){
tone(17, REST);
alarm_toggle = false;
}
}
}