/*********
Rui Santos
Complete instructions at https://RandomNerdTutorials.com/esp32-wi-fi-manager-asyncwebserver/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
#include <Arduino.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <AsyncTCP.h>
#include "SPIFFS.h"
#include <Preferences.h>
Preferences pref;
bool testledState;
#include "Settings.h"
String uartmsg = "";
String volume = "";
String source = "";
String mute = "";
String play = "";
Settings settings;
#define RX_PIN 16 // Serial2 RX to Amp TX
#define TX_PIN 17
// Potentiometer is connected to GPIO 34 (Analog ADC1_CH6)
const int volumePotPin = 32;
const int bassPotPin = 33;
const int trebblePotPin = 34;
const int buttonstri1PotPin = 39;
const int buttonstrip2PotPin = 36;
// variable for storing the potentiometer value
/*int volumePotValue = 0;
int trebblePotValue = 0;
int bassPotValue = 0;*/
int volumeValue = 0;
int bassValue = 0;
int trebbleValue = 0;
int buttonstrip1Value = 0;
int buttonstrip2Value = 0;
// int volume = 0;
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define NUMFLAKES 10 // Number of snowflakes in the animation example
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char PROGMEM logo_bmp0[] =
{B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000};
static const unsigned char PROGMEM logo_bmp[] =
{0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00,
0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7F, 0xFC, 0x00, 0x3F, 0xF8, 0x00, 0x00,
0x00, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xC0, 0x00,
0x01, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xF0, 0x00,
0x03, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFC, 0x00,
0x07, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
0x07, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x0F, 0xFE, 0x03, 0xFF, 0xC1, 0xFF, 0xFF, 0x80,
0x0F, 0xFE, 0x07, 0xFE, 0x00, 0x1F, 0xFF, 0xC0,
0x1F, 0xFC, 0x0F, 0xF8, 0x00, 0x07, 0xFF, 0xE0,
0x1F, 0xF8, 0x0F, 0xE0, 0x00, 0x01, 0xFF, 0xE0,
0x3F, 0xF8, 0x1F, 0xC0, 0x00, 0x00, 0xFF, 0xF0,
0x3F, 0xF0, 0x3F, 0x80, 0x00, 0x00, 0x7F, 0xF8,
0x3F, 0xF0, 0x3F, 0x00, 0x1F, 0x00, 0x3F, 0xF8,
0x7F, 0xF0, 0x7F, 0x00, 0x7F, 0xC0, 0x3F, 0xFC,
0x7F, 0xE0, 0x7E, 0x01, 0xFF, 0xF0, 0x1F, 0xFC,
0x7F, 0xE0, 0xFC, 0x03, 0xFF, 0xF8, 0x1F, 0xFE,
0x7F, 0xE0, 0xFC, 0x07, 0xFF, 0xF8, 0x0F, 0xFE,
0xFF, 0xC0, 0xF8, 0x0F, 0xE1, 0xFC, 0x0F, 0xFE,
0xFF, 0xC0, 0xF8, 0x1F, 0xC0, 0x7E, 0x0F, 0xFE,
0xFF, 0xC0, 0xF8, 0x1F, 0x80, 0x7E, 0x07, 0xFF,
0xFF, 0xC0, 0xF8, 0x1F, 0x00, 0x3E, 0x07, 0xFF,
0xFF, 0xC0, 0xF8, 0x3F, 0x00, 0x3E, 0x07, 0xFF,
0xFF, 0xC0, 0xF8, 0x3F, 0x00, 0x3F, 0x07, 0xFF,
0xFF, 0xC0, 0xF8, 0x3F, 0xF8, 0x1F, 0x07, 0xFF,
0xFF, 0xC0, 0xF8, 0x1F, 0xF8, 0x3F, 0x07, 0xFF,
0xFF, 0xC0, 0xF8, 0x1F, 0xF0, 0x3F, 0x07, 0xFF,
0xFF, 0xC0, 0xF8, 0x0F, 0xF0, 0x3E, 0x07, 0xFF,
0xFF, 0xE0, 0xFC, 0x03, 0xC0, 0x7E, 0x0F, 0xFF,
0xFF, 0xE0, 0x7C, 0x00, 0x00, 0x7E, 0x0F, 0xFF,
0x7F, 0xE0, 0x7E, 0x00, 0x00, 0xFE, 0x0F, 0xFE,
0x7F, 0xF0, 0x3F, 0x00, 0x01, 0xFC, 0x1F, 0xFE,
0x7F, 0xF0, 0x1F, 0x80, 0x03, 0xF8, 0x1F, 0xFE,
0x7F, 0xF0, 0x1F, 0xE0, 0x0F, 0xF8, 0x1F, 0xFE,
0x7F, 0xF8, 0x0F, 0xFC, 0xFF, 0xF0, 0x3F, 0xFC,
0x3F, 0xF8, 0x07, 0xFF, 0xFF, 0xE0, 0x7F, 0xFC,
0x3F, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x7F, 0xFC,
0x1F, 0xFE, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xF8,
0x1F, 0xFF, 0x00, 0x3F, 0xFC, 0x01, 0xFF, 0xF8,
0x1F, 0xFF, 0x80, 0x03, 0xC0, 0x03, 0xFF, 0xF0,
0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xE0,
0x07, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xE0,
0x07, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xC0,
0x03, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0x80,
0x01, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0x00,
0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00,
0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00,
0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0x00};
void scanwifi();
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Create an Event Source on /events
AsyncEventSource events("/events");
// Search for parameter in HTTP POST request
const char *PARAM_INPUT_1 = "ssid";
const char *PARAM_INPUT_2 = "pass";
const char *PARAM_INPUT_3 = "ip";
const char *PARAM_INPUT_4 = "gateway";
// Variables to save values from HTML form
String ssid;
String pass;
String ip;
String gateway;
// File paths to save input values permanently
const char *ssidPath = "/ssid.txt";
const char *passPath = "/pass.txt";
const char *ipPath = "/ip.txt";
const char *gatewayPath = "/gateway.txt";
IPAddress localIP;
// IPAddress localIP(192, 168, 1, 200); // hardcoded
// Set your Gateway IP address
IPAddress localGateway;
// IPAddress localGateway(192, 168, 1, 1); //hardcoded
IPAddress subnet(255, 255, 0, 0);
// Timer variables
unsigned long previousMillis = 0;
const long interval = 10000; // interval to wait for Wi-Fi connection (milliseconds)
// Set LED GPIO
const int ledPin = 4;
// Stores LED state
String ledState;
void sendUARTMessage(String command, String message)
{
String uartMsg;
uartMsg = command + ":" + message + ";";
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.print("send UART: ");
display.print(uartMsg);
display.display();
Serial.print("\nSend UART msg");
Serial.print(uartMsg);
Serial.println("**");
Serial2.flush();
Serial2.write(uartMsg.c_str());
// Serial2.write("NXT;");
}
// Initialize SPIFFS
void initSPIFFS()
{
if (!SPIFFS.begin(true))
{
Serial.println("An error has occurred while mounting SPIFFS");
}
Serial.println("SPIFFS mounted successfully");
}
// Read File from SPIFFS
String readFile(fs::FS &fs, const char *path)
{
Serial.printf("Reading file: %s\r\n", path);
File file = fs.open(path);
if (!file || file.isDirectory())
{
Serial.println("- failed to open file for reading");
return String();
}
String fileContent;
while (file.available())
{
fileContent = file.readStringUntil('\n');
break;
}
return fileContent;
}
// Write file to SPIFFS
void writeFile(fs::FS &fs, const char *path, const char *message)
{
Serial.printf("Writing file: %s\r\n", path);
File file = fs.open(path, FILE_WRITE);
if (!file)
{
Serial.println("- failed to open file for writing");
return;
}
if (file.print(message))
{
Serial.println("- file written");
}
else
{
Serial.println("- write failed");
}
}
// Initialize WiFi
bool initWiFi()
{
if (ssid == "" || ip == "")
{
Serial.println("Undefined SSID or IP address.");
return false;
}
WiFi.mode(WIFI_STA);
localIP.fromString(ip.c_str());
localGateway.fromString(gateway.c_str());
if (!WiFi.config(localIP, localGateway, subnet))
{
Serial.println("STA Failed to configure");
return false;
}
WiFi.begin(ssid.c_str(), pass.c_str());
Serial.println("Connecting to WiFi...");
unsigned long currentMillis = millis();
previousMillis = currentMillis;
while (WiFi.status() != WL_CONNECTED)
{
currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
Serial.println("Failed to connect.");
return false;
}
}
Serial.println(WiFi.localIP());
return true;
}
// Replaces placeholder with LED state value
String processor(const String &var)
{
if (var == "STATE")
{
if (digitalRead(ledPin))
{
ledState = "ON";
}
else
{
ledState = "OFF";
}
return ledState;
}
String buttonstate = "button-off";
if (var == "BUTTONSTATE")
{
buttonstate = "button-on";
return buttonstate;
}
String msg = "";
if (var == "UART")
{
msg = uartmsg;
return msg;
}
if (var == "VOL")
{
msg = volume;
return msg;
}
if (var == "SRC")
{
msg = source;
return msg;
}
if (var == "MUT")
{
msg = mute;
return msg;
}
if (var == "PLA")
{
msg = play;
return msg;
}
return String();
}
void testdrawline()
{
int16_t i;
display.clearDisplay(); // Clear display buffer
for (i = 0; i < display.width(); i += 4)
{
display.drawLine(0, 0, i, display.height() - 1, WHITE);
display.display(); // Update screen with each newly-drawn line
delay(1);
}
for (i = 0; i < display.height(); i += 4)
{
display.drawLine(0, 0, display.width() - 1, i, WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for (i = 0; i < display.width(); i += 4)
{
display.drawLine(0, display.height() - 1, i, 0, WHITE);
display.display();
delay(1);
}
for (i = display.height() - 1; i >= 0; i -= 4)
{
display.drawLine(0, display.height() - 1, display.width() - 1, i, WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for (i = display.width() - 1; i >= 0; i -= 4)
{
display.drawLine(display.width() - 1, display.height() - 1, i, 0, WHITE);
display.display();
delay(1);
}
for (i = display.height() - 1; i >= 0; i -= 4)
{
display.drawLine(display.width() - 1, display.height() - 1, 0, i, WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for (i = 0; i < display.height(); i += 4)
{
display.drawLine(display.width() - 1, 0, 0, i, WHITE);
display.display();
delay(1);
}
for (i = 0; i < display.width(); i += 4)
{
display.drawLine(display.width() - 1, 0, i, display.height() - 1, WHITE);
display.display();
delay(1);
}
delay(2000); // Pause for 2 seconds
}
void testdrawrect(void)
{
display.clearDisplay();
for (int16_t i = 0; i < display.height() / 2; i += 2)
{
display.drawRect(i, i, display.width() - 2 * i, display.height() - 2 * i, WHITE);
display.display(); // Update screen with each newly-drawn rectangle
delay(1);
}
delay(2000);
}
void testfillrect(void)
{
display.clearDisplay();
for (int16_t i = 0; i < display.height() / 2; i += 3)
{
// The INVERSE color is used so rectangles alternate white/black
display.fillRect(i, i, display.width() - i * 2, display.height() - i * 2, INVERSE);
display.display(); // Update screen with each newly-drawn rectangle
delay(1);
}
delay(2000);
}
void testdrawcircle(void)
{
display.clearDisplay();
for (int16_t i = 0; i < max(display.width(), display.height()) / 2; i += 2)
{
display.drawCircle(display.width() / 2, display.height() / 2, i, WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfillcircle(void)
{
display.clearDisplay();
for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 3)
{
// The INVERSE color is used so circles alternate white/black
display.fillCircle(display.width() / 2, display.height() / 2, i, INVERSE);
display.display(); // Update screen with each newly-drawn circle
delay(1);
}
delay(2000);
}
void testdrawroundrect(void)
{
display.clearDisplay();
for (int16_t i = 0; i < display.height() / 2 - 2; i += 2)
{
display.drawRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i,
display.height() / 4, WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfillroundrect(void)
{
display.clearDisplay();
for (int16_t i = 0; i < display.height() / 2 - 2; i += 2)
{
// The INVERSE color is used so round-rects alternate white/black
display.fillRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i,
display.height() / 4, INVERSE);
display.display();
delay(1);
}
delay(2000);
}
void testdrawtriangle(void)
{
display.clearDisplay();
for (int16_t i = 0; i < max(display.width(), display.height()) / 2; i += 5)
{
display.drawTriangle(
display.width() / 2, display.height() / 2 - i,
display.width() / 2 - i, display.height() / 2 + i,
display.width() / 2 + i, display.height() / 2 + i, WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfilltriangle(void)
{
display.clearDisplay();
for (int16_t i = max(display.width(), display.height()) / 2; i > 0; i -= 5)
{
// The INVERSE color is used so triangles alternate white/black
display.fillTriangle(
display.width() / 2, display.height() / 2 - i,
display.width() / 2 - i, display.height() / 2 + i,
display.width() / 2 + i, display.height() / 2 + i, INVERSE);
display.display();
delay(1);
}
delay(2000);
}
void testdrawchar(void)
{
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.cp437(true); // Use full 256 char 'Code Page 437' font
// Not all the characters will fit on the display. This is normal.
// Library will draw what it can and the rest will be clipped.
for (int16_t i = 0; i < 256; i++)
{
if (i == '\n')
display.write(' ');
else
display.write(i);
}
display.display();
delay(2000);
}
void testdrawstyles(void)
{
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("Hello, world!"));
display.setTextColor(BLACK, WHITE); // Draw 'inverse' text
display.println(3.141592);
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(WHITE);
display.print(F("0x"));
display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
}
void testscrolltext(void)
{
display.clearDisplay();
display.setTextSize(2); // Draw 2X-scale text
display.setTextColor(WHITE);
display.setCursor(10, 0);
display.println(F("scroll"));
display.display(); // Show initial text
delay(100);
// Scroll in various directions, pausing in-between:
display.startscrollright(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrollleft(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrolldiagright(0x00, 0x07);
delay(2000);
display.startscrolldiagleft(0x00, 0x07);
delay(2000);
display.stopscroll();
delay(1000);
}
void testdrawbitmap(void)
{
display.clearDisplay();
display.drawBitmap(
(display.width() - LOGO_WIDTH) / 2,
(display.height() - LOGO_HEIGHT) / 2,
logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
display.display();
delay(1000);
}
#define XPOS 0 // Indexes into the 'icons' array in function below
#define YPOS 1
#define DELTAY 2
void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h)
{
int8_t f, icons[NUMFLAKES][3];
// Initialize 'snowflake' positions
for (f = 0; f < NUMFLAKES; f++)
{
icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
icons[f][YPOS] = -LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
Serial.print(F("x: "));
Serial.print(icons[f][XPOS], DEC);
Serial.print(F(" y: "));
Serial.print(icons[f][YPOS], DEC);
Serial.print(F(" dy: "));
Serial.println(icons[f][DELTAY], DEC);
}
for (;;)
{ // Loop forever...
display.clearDisplay(); // Clear the display buffer
// Draw each snowflake:
for (f = 0; f < NUMFLAKES; f++)
{
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
}
display.display(); // Show the display buffer on the screen
delay(200); // Pause for 1/10 second
// Then update coordinates of each flake...
for (f = 0; f < NUMFLAKES; f++)
{
icons[f][YPOS] += icons[f][DELTAY];
// If snowflake is off the bottom of the screen...
if (icons[f][YPOS] >= display.height())
{
// Reinitialize to a random position, just off the top
icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
icons[f][YPOS] = -LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
}
}
}
}
void setup()
{
// Serial port for debugging purposes
Serial.begin(115200);
Serial.println(F("starting"));
//Create a namespace called "gpio-state" with read/write mode
pref.begin("gpio-state", false);
testledState = pref.getBool("state", false);
Serial.printf("LED state before reset: %d \n", testledState);
testledState = !testledState;
Serial.printf("LED state after put reset: %d \n", testledState);
pref.putBool("state", testledState);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
Serial.println(F("SSD1306 allocation ok"));
/*if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
{ // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;)
;
}*/
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(2000); // Pause for 2 seconds
// Clear the buffer
display.clearDisplay();
// Draw a single pixel in white
display.drawPixel(10, 10, WHITE);
// Show the display buffer on the screen. You MUST call display() after
// drawing commands to make them visible on screen!
display.display();
delay(2000);
// display.display() is NOT necessary after every single drawing command,
// unless that's what you want...rather, you can batch up a bunch of
// drawing operations and then update the screen all at once by calling
// display.display(). These examples demonstrate both approaches...
// testdrawline(); // Draw many lines
// testdrawrect(); // Draw rectangles (outlines)
// testfillrect(); // Draw rectangles (filled)
// testdrawcircle(); // Draw circles (outlines)
// testfillcircle(); // Draw circles (filled)
// testdrawroundrect(); // Draw rounded rectangles (outlines)
// testfillroundrect(); // Draw rounded rectangles (filled)
// testdrawtriangle(); // Draw triangles (outlines)
// testfilltriangle(); // Draw triangles (filled)
// testdrawchar(); // Draw characters of the default font
// testdrawstyles(); // Draw 'stylized' characters
// testscrolltext(); // Draw scrolling text
// testdrawbitmap(); // Draw a small bitmap image
// Invert and restore display, pausing in-between
// display.invertDisplay(true);
// delay(1000);
// display.invertDisplay(false);
// delay(1000);
// testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Animate bitmaps
// Reading potentiometer value
// delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
// Display static text
display.println("Hello, world!--");
display.display();
// scanwifi();
initSPIFFS();
// Serial communication to amp
Serial2.begin(115200, SERIAL_8N1, RX_PIN, TX_PIN);
Serial2.setTimeout(1000);
// Set GPIO 2 as an OUTPUT
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// Load values saved in SPIFFS
ssid = pref.getString("ssid","NETGEAR_2GEXT");
pass = pref.getString("pass","4GE4MEHHFG");
ip = pref.getString("ip","192.168.1.200");
gateway = pref.getString("gateway","192.168.1.1");
Serial.println(ssid);
Serial.println(pass);
Serial.println(ip);
Serial.println(gateway);
/*ssid = readFile(SPIFFS, ssidPath);
pass = readFile(SPIFFS, passPath);
ip = readFile(SPIFFS, ipPath);
gateway = readFile(SPIFFS, gatewayPath);
Serial.println(ssid);
Serial.println(pass);
Serial.println(ip);
Serial.println(gateway);*/
if (initWiFi())
{
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(SPIFFS, "/index.html", "text/html", false, processor); });
server.serveStatic("/", SPIFFS, "/");
// Route to set GPIO state to HIGH
server.on("/on", HTTP_GET, [](AsyncWebServerRequest *request)
{
sendUARTMessage("STA","");
Serial.println("\nSet pin ON");
digitalWrite(ledPin, HIGH);
request->send(SPIFFS, "/index.html", "text/html", false, processor); });
// Route to set GPIO state to LOW
server.on("/off", HTTP_GET, [](AsyncWebServerRequest *request)
{
sendUARTMessage("NXT","");
Serial.println("\nSet pin OFF");
digitalWrite(ledPin, LOW);
request->send(SPIFFS, "/index.html", "text/html", false, processor); });
// Handle Web Server Events
events.onConnect([](AsyncEventSourceClient *client)
{
if(client->lastId()){
Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
}
// send event with message "hello!", id current millis
// and set reconnect delay to 1 second
client->send("hello!", NULL, millis(), 10000); });
server.addHandler(&events);
server.begin();
}
else
{
// Connect to Wi-Fi network with SSID and password
Serial.println("Setting AP (Access Point)");
// NULL sets an open Access Point
// WiFi.softAP("ESP-WIFI-MANAGER", NULL);
Serial.println("\n[*] Creating AP");
WiFi.mode(WIFI_AP);
WiFi.softAP("provola00", "provola00");
Serial.print("[+] AP Created with IP Gateway ");
Serial.println(WiFi.softAPIP());
// Serial.print("AP IP address: ");
// Serial.println(IP);
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send(SPIFFS, "/wifimanager.html", "text/html"); });
server.serveStatic("/", SPIFFS, "/");
server.on("/", HTTP_POST, [](AsyncWebServerRequest *request)
{
int params = request->params();
for(int i=0;i<params;i++){
AsyncWebParameter* p = request->getParam(i);
if(p->isPost()){
// HTTP POST ssid value
if (p->name() == PARAM_INPUT_1) {
ssid = p->value().c_str();
Serial.print("SSID set to: ");
Serial.println(ssid);
// Write file to save value
//writeFile(SPIFFS, ssidPath, ssid.c_str());
pref.putString("ssid",ssid);
}
// HTTP POST pass value
if (p->name() == PARAM_INPUT_2) {
pass = p->value().c_str();
Serial.print("Password set to: ");
Serial.println(pass);
// Write file to save value
//writeFile(SPIFFS, passPath, pass.c_str());
pref.putString("pass",pass);
}
// HTTP POST ip value
if (p->name() == PARAM_INPUT_3) {
ip = p->value().c_str();
Serial.print("IP Address set to: ");
Serial.println(ip);
// Write file to save value
//writeFile(SPIFFS, ipPath, ip.c_str());
pref.putString("ip",ip);
}
// HTTP POST gateway value
if (p->name() == PARAM_INPUT_4) {
gateway = p->value().c_str();
Serial.print("Gateway set to: ");
Serial.println(gateway);
// Write file to save value
//writeFile(SPIFFS, gatewayPath, gateway.c_str());
pref.putString("gateway",gateway);
}
//Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
}
}
request->send(200, "text/plain", "Done. ESP will restart, connect to your router and go to IP address: " + ip);
delay(3000);
ESP.restart(); });
server.begin();
}
// Force status update
Serial2.flush();
Serial2.write("STA;");
}
void scanwifi()
{
Serial.println("scan start");
// WiFi.scanNetworks will return the number of networks found
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0)
{
Serial.println("no networks found");
}
else
{
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i)
{
// Print SSID and RSSI for each network found
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
delay(10);
}
}
Serial.println("");
// Wait a bit before scanning again
delay(5000);
}
void UARTReceive()
{
if (Serial2.available() > 0)
{
// events.send(String("14.1").c_str(),"temperature",millis());
events.send("ricevuto", "message", millis(), 10000);
String ampData = Serial2.readStringUntil('\n');
ampData.trim();
Serial.print("areceived: ");
Serial.println(ampData);
uartmsg = ampData;
int index = ampData.indexOf(":");
String command = ampData.substring(0, index);
// Serial.println(command);
String param = ampData.substring(index + 1, ampData.length() - 1);
// Serial.println(param);
events.send(ampData.c_str(), "uartmsg", millis(), 10000);
events.send(param.c_str(), command.c_str(), millis(), 10000);
// events.send("message",command.c_str(),millis());
#ifdef aaaaaaaa
if (command.equals("VER"))
{
Serial.println("command VER");
settings.firmware = param;
}
if (command.equals("STA"))
{
Serial.println("command STA");
// source
index = param.indexOf(","); // STA:LINE-IN,0,30,0,0,1,1,0,1,0;
String source = param.substring(0, index);
settings.source = source;
Serial.println(source);
param = param.substring(index + 1, ampData.length() - 1);
// mute
index = param.indexOf(",");
String mute = param.substring(0, index);
if (mute.equals("0"))
settings.mute = false;
else
settings.mute = true;
param = param.substring(index + 1, ampData.length() - 1);
// volume
index = param.indexOf(",");
String volume = param.substring(0, index);
settings.volume = volume.toInt();
param = param.substring(index + 1, ampData.length() - 1);
// trebble
index = param.indexOf(",");
String trebble = param.substring(0, index);
settings.trebble = trebble.toInt();
param = param.substring(index + 1, ampData.length() - 1);
// bass
index = param.indexOf(",");
String bass = param.substring(0, index);
settings.bass = bass.toInt();
param = param.substring(index + 1, ampData.length() - 1);
// net
index = param.indexOf(",");
String net = param.substring(0, index);
if (net.equals("0"))
settings.net = false;
else
settings.net = true;
param = param.substring(index + 1, ampData.length() - 1);
// internet
index = param.indexOf(",");
String internet = param.substring(0, index);
if (internet.equals("0"))
settings.internet = false;
else
settings.internet = true;
param = param.substring(index + 1, ampData.length() - 1);
// playing
index = param.indexOf(",");
String playing = param.substring(0, index);
if (playing.equals("0"))
settings.playing = false;
else
settings.playing = true;
param = param.substring(index + 1, ampData.length() - 1);
// led
index = param.indexOf(",");
String led = param.substring(0, index);
if (led.equals("0"))
settings.led = false;
else
settings.led = true;
param = param.substring(index + 1, ampData.length() - 1);
// upgrading
index = param.indexOf(";");
String upgrading = param.substring(0, index);
if (upgrading.equals("0"))
settings.upgrading = false;
else
settings.upgrading = true;
param = param.substring(index + 1, ampData.length() - 1);
}
else if (command.equals("SYS"))
{
Serial.println("command SYS");
settings.status = param;
}
else if (command.equals("AUD"))
{
Serial.println("command AUD");
if (param.equals("0"))
settings.audio_output = false;
else
settings.audio_output = true;
settings.audio_output = param;
}
else if (command.equals("SRC"))
{
Serial.println("command SRC");
settings.source = param;
}
else if (command.equals("VOL"))
{
Serial.println("command VOL");
settings.volume = param.toInt();
}
else if (command.equals("BAS"))
{
Serial.println("command BAS");
settings.bass = param.toInt();
}
else if (command.equals("TRE"))
{
Serial.println("command TRE");
settings.trebble = param.toInt();
}
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
String text = "UART received: " + ampData;
display.println(text);
display.setCursor(0, 20); // Start at top-left corner
text = "volume:" + String(settings.volume);
display.println(text);
/*display.setCursor(0,40); // Start at top-left corner
display.print(command);
display.print("-");
display.println(param);*/
display.display();
#endif
}
}
void loop()
{
// Reading potentiometer value
int oldVolumeValue = volumeValue;
volumeValue = analogRead(volumePotPin);
Serial.print("volumeValue = ");
Serial.println(volumeValue);
if (volumeValue != oldVolumeValue) {
//Serial.print("volumeValue = ");
//Serial.print(volumeValue);
String str = String(volumeValue);
events.send(str.c_str() , "volume", millis(), 10000);
}
#ifdef debug
int oldBassValue = bassValue;
bassValue = analogRead(bassPotPin);
if (bassValue != oldBassValue) {
//Serial.print(" bassValue = ");
//Serial.print(bassValue);
String str = String(bassValue);
events.send(str.c_str() , "bass", millis(), 10000);
}
int oldTrebbleValue = trebbleValue;
trebbleValue = analogRead(trebblePotPin);
if (trebbleValue != oldTrebbleValue) {
//Serial.print("trebbleValue = ");
//Serial.print(trebbleValue);
String str = String(trebbleValue);
events.send(str.c_str() , "trebble", millis(), 10000);
}
int oldbuttonstrip1Value = buttonstrip1Value;
buttonstrip1Value = analogRead(buttonstri1PotPin);
if (buttonstrip1Value != oldbuttonstrip1Value) {
String str = String(buttonstrip1Value);
events.send(str.c_str() , "buttonstrip1", millis(), 10000);
}
int oldbuttonstrip2Value = buttonstrip2Value;
buttonstrip2Value = analogRead(buttonstrip2PotPin);
if (buttonstrip2Value != oldbuttonstrip2Value) {
String str = String(buttonstrip2Value);
events.send(str.c_str() , "buttonstrip2", millis(), 10000);
}
Serial.print(volumeValue);
Serial.print(",");
Serial.print(bassValue);
Serial.print(",");
Serial.print(trebbleValue);
Serial.print(",");
Serial.print(buttonstrip1Value);
Serial.print(",");
Serial.println(buttonstrip2Value);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 1);
// Display static text
display.println("Hello, world!--");
display.setTextSize(1);
display.setCursor(0, 20);
String ss = "" + volumeValue;
ss += "," + bassValue;
ss += "," + trebbleValue;
ss += "," + buttonstrip1Value;
ss += "," + buttonstrip2Value;
display.println(ss);
display.display();
#endif
delay(800);
/*trebble = 100 * trebblePotValue / 4095;
if ( abs(trebble - oldTrebble) > 10) {
Serial.print(" trebblePotValue = ");
Serial.print(trebblePotValue);
Serial.print(" - ");
Serial.print(trebble);
Serial.print(" - ");
Serial.print(trebble);
Serial.print(" - ");
Serial.print(oldTrebble);
Serial.print(" - ");
Serial.println(abs(trebble - oldTrebble));
oldTrebble = trebble;
}*/
// delay(500);
UARTReceive();
}