Files
ThatProject/ESP32_TTGO/Walkie-Talkie_Project/Server/Server.ino
2021-03-24 09:39:52 -07:00

195 lines
4.6 KiB
C++

/////////////////////////////////////////////////////////////////
/*
ESP32 | Walkie-Talkie, Half-duplex communication based on WebSocket
Video Tutorial: https://youtu.be/kw30vLdrGE8
Created by Eric Nam (ThatProject)
*/
/////////////////////////////////////////////////////////////////
#include <WiFi.h>
#include <ArduinoWebsockets.h>
#include <TFT_eSPI.h>
#include "Free_Fonts.h"
#include "driver/i2s.h"
#include "Button2.h";
#include "I2s_Setting.h"
#include "Const.h"
#define RIGHT_BUTTON_PIN 35
Button2 rButton = Button2(RIGHT_BUTTON_PIN);
using namespace websockets;
WebsocketsServer server;
WebsocketsClient client;
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite logScreen = TFT_eSprite(&tft);
unsigned long requestTimestamp;
TaskHandle_t i2sReadTaskHandler = NULL;
void setup() {
Serial.begin(115200);
WiFi.softAP(ssid, password);
server.listen(8888);
display_init();
display_ready_screen();
button_init();
i2s_buff_init();
print_log_screen("+ All Ready");
xTaskCreate(pong_task, "pong_task", 2048, NULL, 1, NULL);
}
void loop() {
rButton.loop();
listenForClient();
pollClient();
}
void listenForClient() {
if (server.poll()) {
print_log_screen("+ Client Connected!");
client = server.accept();
client.onMessage(handleMessage);
client.onEvent(handleEvent);
client.send(getStrTimestamp());
requestTimestamp = millis();
}
}
void pollClient() {
client.poll();
}
void handleMessage(WebsocketsClient &client, WebsocketsMessage message) {
requestTimestamp = millis();
int msgLength = message.length();
if(message.type() == MessageType::Binary){
if(states == Listening && msgLength > 0){
i2s_write_data((char*)message.c_str(), msgLength);
}
}else if(message.type() == MessageType::Text){
if(states == Idle){
states = Listening;
i2s_TX_init();
client.send(message.data());
print_log_screen("* Listening Mode *");
}else if(states == Listening){
states = Idle;
i2s_TX_uninst();
print_log_screen("* IDLE Mode *");
}
}
}
void handleEvent(WebsocketsClient &client, WebsocketsEvent event, String data) {
if (event == WebsocketsEvent::ConnectionClosed) {
print_log_screen("- Client Disconnected!");
if(states == Listening){
states = Idle;
i2s_TX_uninst();
}
}
}
static void i2s_read_task(void *arg)
{
while (1) {
i2s_read_data();
if(client.available() && states == Speaking){
requestTimestamp = millis();
client.sendBinary((const char*)flash_write_buff, I2S_READ_LEN);
}
}
}
static void pong_task(void *arg){
while (1) {
if(client.available() && millis() - requestTimestamp > 5000) {
client.close();
}
vTaskDelay(1000);
}
}
void pressed(Button2& btn) {
if(btn == rButton && states == Idle){
print_log_screen("* Speaking Mode *");
client.send(getStrTimestamp());
states = Speaking;
i2s_RX_init();
xTaskCreate(i2s_read_task, "i2s_read_task", 4096, NULL, 1, &i2sReadTaskHandler);
}
}
void released(Button2& btn) {
if(btn == rButton && states == Speaking){
states = Idle;
print_log_screen("* IDLE Mode *");
delay(100);
if( i2sReadTaskHandler != NULL ){
vTaskDelete( i2sReadTaskHandler );
i2sReadTaskHandler = NULL;
}
delay(100);
client.send(getStrTimestamp());
i2s_RX_uninst();
}
}
String getStrTimestamp(){
return (String)millis();
}
void button_init(){
rButton.setPressedHandler(pressed);
rButton.setReleasedHandler(released);
}
void display_init(){
tft.begin();
tft.setRotation(0);
tft.setTextColor(TFT_WHITE,TFT_BLACK);
tft.fillScreen(TFT_BLACK);
logScreen.setColorDepth(8);
logScreen.createSprite(tft.width(), tft.height()/2);
logScreen.fillSprite(TFT_BLUE);
logScreen.setScrollRect(0, 0, tft.width(), tft.height()/2, TFT_BLUE);
logScreen.setTextColor(TFT_WHITE);
logScreen.setTextDatum(TL_DATUM);
}
void display_ready_screen(){
tft.fillScreen(TFT_BLACK);
tft.setTextDatum(TL_DATUM);
tft.setFreeFont(FF21);
tft.setTextColor(TFT_SKYBLUE, TFT_BLACK);
tft.drawString("ESP32-ESP32", 0, 10, GFXFF);
tft.setFreeFont(FF23);
tft.setTextColor(TFT_SILVER, TFT_BLACK);
tft.drawString("Walkie", 0, 35, GFXFF);
tft.setTextColor(TFT_GOLD, TFT_BLACK);
tft.drawString("Talkie", 30, 60, GFXFF);
tft.setTextDatum(MC_DATUM);
tft.setFreeFont(FF21);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString(deviceRole == Server ? "[Server Ready]" : "[Client Ready]", tft.width()/2, 100, GFXFF);
}
void print_log_screen(String text){
logScreen.drawString(text, 0, -1, 2);
logScreen.pushSprite(0, tft.height()/2);
logScreen.scroll(0,16);
}