From 18131e80fbf47d2f9e8a45a43d0df64ecf694041 Mon Sep 17 00:00:00 2001 From: Eric Date: Tue, 9 Mar 2021 14:21:41 -0800 Subject: [PATCH] Wireless Wiretap System using 2x ESP32, INMP441 & MAX98357A --- .../Client_INMP441/Client_INMP441.ino | 113 ++++++ .../Server_MAX98357A_TTGO/Free_Fonts.h | 379 ++++++++++++++++++ .../Server_MAX98357A_TTGO.ino | 156 +++++++ 3 files changed, 648 insertions(+) create mode 100644 ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Client_INMP441/Client_INMP441.ino create mode 100644 ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Free_Fonts.h create mode 100644 ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Server_MAX98357A_TTGO.ino diff --git a/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Client_INMP441/Client_INMP441.ino b/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Client_INMP441/Client_INMP441.ino new file mode 100644 index 0000000..913faa6 --- /dev/null +++ b/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Client_INMP441/Client_INMP441.ino @@ -0,0 +1,113 @@ +#include +#include +#include "driver/i2s.h" + +#define I2S_WS_RX 27 +#define I2S_SCK_RX 14 +#define I2S_SD_RX 12 + +#define I2S_PORT I2S_NUM_1 +#define I2S_SAMPLE_RATE (16000) +#define I2S_SAMPLE_BITS (32) +#define I2S_READ_LEN (1024) + +const char* ssid = "ESP32-THAT-PROJECT"; +const char* password = "California"; + +const char* websockets_server_host = "192.168.4.1"; +const uint16_t websockets_server_port = 8888; + +TaskHandle_t i2sADCHandler = NULL; + +using namespace websockets; +WebsocketsClient client; + +const i2s_config_t i2s_config_rx = { + .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = I2S_SAMPLE_RATE, + .bits_per_sample = i2s_bits_per_sample_t(I2S_SAMPLE_BITS), + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // default interrupt priority + .dma_buf_count = 32, + .dma_buf_len = 64 +}; + +const i2s_pin_config_t pin_config_rx = { + .bck_io_num = I2S_SCK_RX, + .ws_io_num = I2S_WS_RX, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD_RX +}; + +void setup() { + Serial.begin(115200); + start_to_connect(); +} + +void start_to_connect(){ + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println(""); + Serial.println("WiFi connected"); + Serial.println("Socket Connecting"); + + client.onEvent(onEventsCallback); + while(!client.connect(websockets_server_host, websockets_server_port, "/")){ + delay(500); + Serial.print("."); + } + + Serial.println("Socket Connected!"); +} + +void i2s_adc_data_scale(uint8_t * d_buff, uint8_t* s_buff, uint32_t len) +{ + uint32_t j = 0; + uint32_t dac_value = 0; + for (int i = 0; i < len; i += 2) { + dac_value = ((((uint16_t) (s_buff[i + 1] & 0xf) << 8) | ((s_buff[i + 0])))); + d_buff[j++] = 0; + d_buff[j++] = dac_value * 256 / 2048 ; + } +} + +static void i2s_adc_task(void *arg) +{ + i2s_driver_install(I2S_NUM_1, &i2s_config_rx, 0, NULL); + i2s_set_pin(I2S_NUM_1, &pin_config_rx); + + int i2s_read_len = I2S_READ_LEN; + size_t bytes_read; + + char* i2s_read_buff = (char*) calloc(i2s_read_len, sizeof(char)); + uint8_t* flash_write_buff = (uint8_t*) calloc(i2s_read_len, sizeof(char)); + + while (1) { + i2s_read(I2S_PORT, (void*) i2s_read_buff, i2s_read_len, &bytes_read, portMAX_DELAY); + i2s_adc_data_scale(flash_write_buff, (uint8_t*)i2s_read_buff, i2s_read_len); + client.sendBinary((const char*)flash_write_buff, i2s_read_len); + ets_printf("Never Used Stack Size: %u\n", uxTaskGetStackHighWaterMark(NULL)); + } + + free(i2s_read_buff); + i2s_read_buff = NULL; + free(flash_write_buff); + flash_write_buff = NULL; +} + +void loop() { +} + +void onEventsCallback(WebsocketsEvent event, String data) { + if(event == WebsocketsEvent::ConnectionOpened) { + Serial.println("Connnection Opened"); + xTaskCreate(i2s_adc_task, "i2s_adc_task", 4096, NULL, 1, &i2sADCHandler); + } else if(event == WebsocketsEvent::ConnectionClosed) { + Serial.println("Connnection Closed"); + ESP.restart(); + } +} diff --git a/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Free_Fonts.h b/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Free_Fonts.h new file mode 100644 index 0000000..7c0a264 --- /dev/null +++ b/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Free_Fonts.h @@ -0,0 +1,379 @@ +// Attach this header file to your sketch to use the GFX Free Fonts. You can write +// sketches without it, but it makes referencing them easier. + +// This calls up ALL the fonts but they only get loaded if you actually +// use them in your sketch. +// +// No changes are needed to this header file unless new fonts are added to the +// library "Fonts/GFXFF" folder. +// +// To save a lot of typing long names, each font can easily be referenced in the +// sketch in three ways, either with: +// +// 1. Font file name with the & in front such as &FreeSansBoldOblique24pt7b +// an example being: +// +// tft.setFreeFont(&FreeSansBoldOblique24pt7b); +// +// 2. FF# where # is a number determined by looking at the list below +// an example being: +// +// tft.setFreeFont(FF32); +// +// 3. An abbreviation of the file name. Look at the list below to see +// the abbreviations used, for example: +// +// tft.setFreeFont(FSSBO24) +// +// Where the letters mean: +// F = Free font +// M = Mono +// SS = Sans Serif (double S to distinguish is form serif fonts) +// S = Serif +// B = Bold +// O = Oblique (letter O not zero) +// I = Italic +// # = point size, either 9, 12, 18 or 24 +// +// Setting the font to NULL will select the GLCD font: +// +// tft.setFreeFont(NULL); // Set font to GLCD + + +#ifdef LOAD_GFXFF // Only include the fonts if LOAD_GFXFF is defined in User_Setup.h + +// Use these when printing or drawing text in GLCD and high rendering speed fonts +// Call up the font using tft.setTextFont() +#define GFXFF 1 +#define GLCD 0 +#define FONT2 2 +#define FONT4 4 +#define FONT6 6 +#define FONT7 7 +#define FONT8 8 + +// Use the following when calling tft.setFreeFont() +// +// Reserved for GLCD font // FF0 +// + +#define TT1 &TomThumb + +#define FM9 &FreeMono9pt7b +#define FM12 &FreeMono12pt7b +#define FM18 &FreeMono18pt7b +#define FM24 &FreeMono24pt7b + +#define FMB9 &FreeMonoBold9pt7b +#define FMB12 &FreeMonoBold12pt7b +#define FMB18 &FreeMonoBold18pt7b +#define FMB24 &FreeMonoBold24pt7b + +#define FMO9 &FreeMonoOblique9pt7b +#define FMO12 &FreeMonoOblique12pt7b +#define FMO18 &FreeMonoOblique18pt7b +#define FMO24 &FreeMonoOblique24pt7b + +#define FMBO9 &FreeMonoBoldOblique9pt7b +#define FMBO12 &FreeMonoBoldOblique12pt7b +#define FMBO18 &FreeMonoBoldOblique18pt7b +#define FMBO24 &FreeMonoBoldOblique24pt7b + +#define FSS9 &FreeSans9pt7b +#define FSS12 &FreeSans12pt7b +#define FSS18 &FreeSans18pt7b +#define FSS24 &FreeSans24pt7b + +#define FSSB9 &FreeSansBold9pt7b +#define FSSB12 &FreeSansBold12pt7b +#define FSSB18 &FreeSansBold18pt7b +#define FSSB24 &FreeSansBold24pt7b + +#define FSSO9 &FreeSansOblique9pt7b +#define FSSO12 &FreeSansOblique12pt7b +#define FSSO18 &FreeSansOblique18pt7b +#define FSSO24 &FreeSansOblique24pt7b + +#define FSSBO9 &FreeSansBoldOblique9pt7b +#define FSSBO12 &FreeSansBoldOblique12pt7b +#define FSSBO18 &FreeSansBoldOblique18pt7b +#define FSSBO24 &FreeSansBoldOblique24pt7b + +#define FS9 &FreeSerif9pt7b +#define FS12 &FreeSerif12pt7b +#define FS18 &FreeSerif18pt7b +#define FS24 &FreeSerif24pt7b + +#define FSI9 &FreeSerifItalic9pt7b +#define FSI12 &FreeSerifItalic12pt7b +#define FSI19 &FreeSerifItalic18pt7b +#define FSI24 &FreeSerifItalic24pt7b + +#define FSB9 &FreeSerifBold9pt7b +#define FSB12 &FreeSerifBold12pt7b +#define FSB18 &FreeSerifBold18pt7b +#define FSB24 &FreeSerifBold24pt7b + +#define FSBI9 &FreeSerifBoldItalic9pt7b +#define FSBI12 &FreeSerifBoldItalic12pt7b +#define FSBI18 &FreeSerifBoldItalic18pt7b +#define FSBI24 &FreeSerifBoldItalic24pt7b + +#define FF0 NULL //ff0 reserved for GLCD +#define FF1 &FreeMono9pt7b +#define FF2 &FreeMono12pt7b +#define FF3 &FreeMono18pt7b +#define FF4 &FreeMono24pt7b + +#define FF5 &FreeMonoBold9pt7b +#define FF6 &FreeMonoBold12pt7b +#define FF7 &FreeMonoBold18pt7b +#define FF8 &FreeMonoBold24pt7b + +#define FF9 &FreeMonoOblique9pt7b +#define FF10 &FreeMonoOblique12pt7b +#define FF11 &FreeMonoOblique18pt7b +#define FF12 &FreeMonoOblique24pt7b + +#define FF13 &FreeMonoBoldOblique9pt7b +#define FF14 &FreeMonoBoldOblique12pt7b +#define FF15 &FreeMonoBoldOblique18pt7b +#define FF16 &FreeMonoBoldOblique24pt7b + +#define FF17 &FreeSans9pt7b +#define FF18 &FreeSans12pt7b +#define FF19 &FreeSans18pt7b +#define FF20 &FreeSans24pt7b + +#define FF21 &FreeSansBold9pt7b +#define FF22 &FreeSansBold12pt7b +#define FF23 &FreeSansBold18pt7b +#define FF24 &FreeSansBold24pt7b + +#define FF25 &FreeSansOblique9pt7b +#define FF26 &FreeSansOblique12pt7b +#define FF27 &FreeSansOblique18pt7b +#define FF28 &FreeSansOblique24pt7b + +#define FF29 &FreeSansBoldOblique9pt7b +#define FF30 &FreeSansBoldOblique12pt7b +#define FF31 &FreeSansBoldOblique18pt7b +#define FF32 &FreeSansBoldOblique24pt7b + +#define FF33 &FreeSerif9pt7b +#define FF34 &FreeSerif12pt7b +#define FF35 &FreeSerif18pt7b +#define FF36 &FreeSerif24pt7b + +#define FF37 &FreeSerifItalic9pt7b +#define FF38 &FreeSerifItalic12pt7b +#define FF39 &FreeSerifItalic18pt7b +#define FF40 &FreeSerifItalic24pt7b + +#define FF41 &FreeSerifBold9pt7b +#define FF42 &FreeSerifBold12pt7b +#define FF43 &FreeSerifBold18pt7b +#define FF44 &FreeSerifBold24pt7b + +#define FF45 &FreeSerifBoldItalic9pt7b +#define FF46 &FreeSerifBoldItalic12pt7b +#define FF47 &FreeSerifBoldItalic18pt7b +#define FF48 &FreeSerifBoldItalic24pt7b + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +// Now we define "s"tring versions for easy printing of the font name so: +// tft.println(sFF5); +// will print +// Mono bold 9 +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +#define sFF0 "GLCD" +#define sTT1 "Tom Thumb" +#define sFF1 "Mono 9" +#define sFF2 "Mono 12" +#define sFF3 "Mono 18" +#define sFF4 "Mono 24" + +#define sFF5 "Mono bold 9" +#define sFF6 "Mono bold 12" +#define sFF7 "Mono bold 18" +#define sFF8 "Mono bold 24" + +#define sFF9 "Mono oblique 9" +#define sFF10 "Mono oblique 12" +#define sFF11 "Mono oblique 18" +#define sFF12 "Mono oblique 24" + +#define sFF13 "Mono bold oblique 9" +#define sFF14 "Mono bold oblique 12" +#define sFF15 "Mono bold oblique 18" +#define sFF16 "Mono bold oblique 24" // Full text line is too big for 480 pixel wide screen + +#define sFF17 "Sans 9" +#define sFF18 "Sans 12" +#define sFF19 "Sans 18" +#define sFF20 "Sans 24" + +#define sFF21 "Sans bold 9" +#define sFF22 "Sans bold 12" +#define sFF23 "Sans bold 18" +#define sFF24 "Sans bold 24" + +#define sFF25 "Sans oblique 9" +#define sFF26 "Sans oblique 12" +#define sFF27 "Sans oblique 18" +#define sFF28 "Sans oblique 24" + +#define sFF29 "Sans bold oblique 9" +#define sFF30 "Sans bold oblique 12" +#define sFF31 "Sans bold oblique 18" +#define sFF32 "Sans bold oblique 24" + +#define sFF33 "Serif 9" +#define sFF34 "Serif 12" +#define sFF35 "Serif 18" +#define sFF36 "Serif 24" + +#define sFF37 "Serif italic 9" +#define sFF38 "Serif italic 12" +#define sFF39 "Serif italic 18" +#define sFF40 "Serif italic 24" + +#define sFF41 "Serif bold 9" +#define sFF42 "Serif bold 12" +#define sFF43 "Serif bold 18" +#define sFF44 "Serif bold 24" + +#define sFF45 "Serif bold italic 9" +#define sFF46 "Serif bold italic 12" +#define sFF47 "Serif bold italic 18" +#define sFF48 "Serif bold italic 24" + +#else // LOAD_GFXFF not defined so setup defaults to prevent error messages + +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +// Free fonts are not loaded in User_Setup.h so we must define all as font 1 +// to prevent compile error messages +// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +#define GFXFF 1 +#define GLCD 1 +#define FONT2 2 +#define FONT4 4 +#define FONT6 6 +#define FONT7 7 +#define FONT8 8 + +#define TT1 1 + +#define FF0 1 +#define FF1 1 +#define FF2 1 +#define FF3 1 +#define FF4 1 +#define FF5 1 +#define FF6 1 +#define FF7 1 +#define FF8 1 +#define FF9 1 +#define FF10 1 +#define FF11 1 +#define FF12 1 +#define FF13 1 +#define FF14 1 +#define FF15 1 +#define FF16 1 +#define FF17 1 +#define FF18 1 +#define FF19 1 +#define FF20 1 +#define FF21 1 +#define FF22 1 +#define FF23 1 +#define FF24 1 +#define FF25 1 +#define FF26 1 +#define FF27 1 +#define FF28 1 +#define FF29 1 +#define FF30 1 +#define FF31 1 +#define FF32 1 +#define FF33 1 +#define FF34 1 +#define FF35 1 +#define FF36 1 +#define FF37 1 +#define FF38 1 +#define FF39 1 +#define FF40 1 +#define FF41 1 +#define FF42 1 +#define FF43 1 +#define FF44 1 +#define FF45 1 +#define FF46 1 +#define FF47 1 +#define FF48 1 + +#define FM9 1 +#define FM12 1 +#define FM18 1 +#define FM24 1 + +#define FMB9 1 +#define FMB12 1 +#define FMB18 1 +#define FMB24 1 + +#define FMO9 1 +#define FMO12 1 +#define FMO18 1 +#define FMO24 1 + +#define FMBO9 1 +#define FMBO12 1 +#define FMBO18 1 +#define FMBO24 1 + +#define FSS9 1 +#define FSS12 1 +#define FSS18 1 +#define FSS24 1 + +#define FSSB9 1 +#define FSSB12 1 +#define FSSB18 1 +#define FSSB24 1 + +#define FSSO9 1 +#define FSSO12 1 +#define FSSO18 1 +#define FSSO24 1 + +#define FSSBO9 1 +#define FSSBO12 1 +#define FSSBO18 1 +#define FSSBO24 1 + +#define FS9 1 +#define FS12 1 +#define FS18 1 +#define FS24 1 + +#define FSI9 1 +#define FSI12 1 +#define FSI19 1 +#define FSI24 1 + +#define FSB9 1 +#define FSB12 1 +#define FSB18 1 +#define FSB24 1 + +#define FSBI9 1 +#define FSBI12 1 +#define FSBI18 1 +#define FSBI24 1 + +#endif // LOAD_GFXFF diff --git a/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Server_MAX98357A_TTGO.ino b/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Server_MAX98357A_TTGO.ino new file mode 100644 index 0000000..65e1404 --- /dev/null +++ b/ESP32_MICROPHONE/Wiretap_INMP441_MAX98357A_via_websocket/Server_MAX98357A_TTGO/Server_MAX98357A_TTGO.ino @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include "driver/i2s.h" +#include "Free_Fonts.h" + +#define I2S_WS_TX 12 +#define I2S_SCK_TX 13 +#define I2S_DATA_OUT_TX 15 + +#define I2S_PORT I2S_NUM_0 +#define I2S_SAMPLE_RATE (16000) +#define I2S_SAMPLE_BITS (32) +#define UPDATE_INTERVAL (500) + +const char* ssid = "ESP32-THAT-PROJECT"; +const char* password = "California"; + +using namespace websockets; +WebsocketsServer server; +WebsocketsClient client; + +TFT_eSPI tft = TFT_eSPI(); +TFT_eSprite graph = TFT_eSprite(&tft); + +const i2s_config_t i2s_config_tx = { + .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_TX), + .sample_rate = I2S_SAMPLE_RATE, + .bits_per_sample = i2s_bits_per_sample_t(I2S_SAMPLE_BITS), + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 32, + .dma_buf_len = 64 +}; + +const i2s_pin_config_t pin_config_tx = { + .bck_io_num = I2S_SCK_TX, + .ws_io_num = I2S_WS_TX, + .data_out_num = I2S_DATA_OUT_TX, + .data_in_num = I2S_PIN_NO_CHANGE +}; + +TaskHandle_t drawGraphTaskHandler = NULL; + +unsigned long last_update_sent = 0; +bool isConnected; +static int sampleValue; + +void setup() { + Serial.begin(115200); + WiFi.softAP(ssid, password); + server.listen(8888); + + displayInit(); + readyScreen(); + + xTaskCreate(server_task, "server_task", 4096, NULL, 1, NULL); +} +static void draw_graph_task(void *arg) +{ + int preHeight = 0; + + while(1){ + if(isConnected){ + int calcHeight = sampleValue; + graph.drawLine(tft.width() - 2, preHeight, tft.width() - 1, calcHeight, 1); + preHeight = calcHeight; + tft.setBitmapColor(TFT_WHITE, TFT_BLACK); + graph.pushSprite(0, 0); + graph.scroll(-2, 0); + }else{ + vTaskDelay(100); + } + } +} + +static void server_task(void *arg) +{ + while(1){ + if(server.poll()){ + client = server.accept(); + i2sInit(); + last_update_sent = millis(); + isConnected = true; + xTaskCreate(draw_graph_task, "draw_graph_task", 2048, NULL, 1, &drawGraphTaskHandler); + } + + if(isConnected && millis() - last_update_sent > UPDATE_INTERVAL) { + vTaskDelete(drawGraphTaskHandler); + Serial.println("Client disconnected! Uninstall I2S driver"); + isConnected = false; + i2s_driver_uninstall(I2S_PORT); + readyScreen(); + } + vTaskDelay(100); + } +} + +void loop() { + i2s_write_from_client(); +} + +void i2s_write_from_client() +{ + if(client.available()){ + last_update_sent = millis(); + client.poll(); + WebsocketsMessage msg = client.readBlocking(); + char *buf_ptr = (char*)msg.c_str(); + int bytes_written = msg.length(); + i2s_write_bytes(I2S_PORT, buf_ptr, bytes_written, portMAX_DELAY); + + int32_t sample = (int32_t) buf_ptr[3] << 24; + sample |= (int32_t) buf_ptr[2] << 16; + sample |= (int32_t) buf_ptr[1] << 8; + sample |= (int32_t) buf_ptr[0]; + + sampleValue = map(sample / 100000, -4000, 4000, 0, tft.height()); + } +} + +void i2sInit(){ + i2s_driver_install(I2S_PORT, &i2s_config_tx, 0, NULL); + i2s_set_pin(I2S_PORT, &pin_config_tx); +} + +void displayInit(){ + tft.begin(); + tft.setRotation(1); + tft.setTextColor(TFT_WHITE,TFT_BLACK); + tft.fillScreen(TFT_BLACK); + graph.setColorDepth(1); + graph.createSprite(tft.width(), tft.height()); + graph.fillSprite(TFT_BLACK); +} + +void readyScreen(){ + tft.fillScreen(TFT_BLACK); + tft.setTextDatum(TL_DATUM); + + tft.setFreeFont(FF21); + tft.setTextColor(TFT_RED, TFT_BLACK); + tft.drawString("WIRELESS", 10, 10, GFXFF); + + tft.setFreeFont(FF24); + tft.setTextColor(TFT_YELLOW, TFT_BLACK); + tft.drawString("WIRETAP", 10, 40, GFXFF); + + tft.setFreeFont(FF21); + tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.drawString("Waiting for the other side", 0, 95, GFXFF); + tft.setFreeFont(FF9); + tft.drawString("Version 0.1", 0, 115, GFXFF); +}