Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 2 | ||||
Software apps and online services | ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
|
Navigating daily life can be a significant challenge for individuals who are blind or visually impaired. Everyday tasks that many take for granted, such as identifying objects, reading signs, or selecting appropriate clothing, often require adaptive strategies and tools.
The absence of visual cues can make interacting with the environment difficult, leading to obstacles in both routine activities and independent living.
SolutionTo address the obstacles that visually impaired people face every day and promote a more independent life, I have designed an innovative A.I. wearable device equipped with a camera, microphone, and speaker. This device captures images of the surroundings with its camera, processes the information using the advanced ChatGPT Vision Model, and provides real-time descriptions of the images.
Users can ask questions about their environment using the built-in microphone and receive clear, spoken feedback through the speaker. This integration of technologies offers a comprehensive solution that enhances independence and simplifies daily interactions.
How it WorksThe device features two buttons: one for taking photos and another for activating the microphone.
Once the user has taken a photo by pressing the respective button, they can press the microphone button to ask brief questions about the image. After a short processing time, the user will receive an audio response through the speaker, providing answers in the language in which the question was asked.
In detail, when the user takes a photo, it is saved in the flash memory of the ESP32 and encoded in base64.
After taking the photo, when the user presses the speak button, the microphone is activated for a few seconds letting the user to ask a question about the image taken.
Once the recording is complete, the audio is sent to Google's Speech-to-Text AI API which returns the transcribed text, then the encoded image and the transcribed text are sent to the ChatGPT Vision AI API that processes the image and text, and returns a response in text form.
This response is sent to the speaker via an I2S audio amplifier, providing the user with spoken feedback.
Users can ask multiple questions about the same photo, or take another photo and inquire about it. All spoken responses are delivered in the same language as the questions asked. The device operates using a 3.7V Li-Po battery, which can be charged via the USB-C port on the XIAO ESP32S3 board.
1.Harvest the Components: The components marked with a "(1)" can be extracted from the MAX98357 Audio Amplifier PCB. This approach is more cost-effective than purchasing the components individually.
To extract the components, you can use either a hot plate or a hot air soldering station. The components obtained from each PCB are as follows:
- MAX98357: X1
- 0805 220pF Cap: x2
- 0805 Ferrite Bead: x2
- 0805 10uF Cap: x1
- 0805 100nF Cap: x1
2. SolderingComponents: BOTTOM
Once you have desoldered all the components from the PCB and gathered the rest of the bill of materials, you will need to solder them onto the new PCB. To do this, you'll use solder paste, a custom stencil, and a spatula. Follow these steps:
1. Secure the PCB using other boards around of the same height (1.6mm).
2. Secure the stencil with tape, ensuring that the holes in the stencil align perfectly with the PCB pads.
3.Apply the solder paste to the pads using a spatula or similar tool.
4. Remove the stencil and verify that the solder paste is applied only to the pads.
5. Place the components onto the PCB, ensuring the correct orientation of the MAX98357 (pay close attention to the dot marking indicating the correct orientation).
Note: The 100K resistor can be omitted; more information on this will be provided later.
6. Solder the components to the PCB using a hot plate or a hot air soldering station.
3. SolderingComponents: TOP
Follow the same steps as in "Soldering Components: BOTTOM." In this case, you can apply solder paste either using the stencil or by hand, or alternatively, you can use soldering wire, as the components have enlarged pads for easier manual soldering.
At this step, you need to decide if you want to solder the XIAO ESP32S3 module directly to the board. If you plan to use the module for other projects, it's best not to solder it directly. Instead, you can use pin sockets in combination with pin headers to connect the module to the board.
In my case, I chose the second option because I had already soldered pin headers to the XIAO ESP32S3 for testing before designing the PCB.
4. Final Components:
The last components to solder to the PCB are:
- Connector for the speaker (also crimp a female/male connector to the speaker).
- Connector for the battery
- Battery Switch
- Cables for battery connection between the PCB and the XIAO ESP32S3 (Solder the terminal "-" of the battery either to BAT-or the thermal PAD, as both are connected to GND)
This last step can be omitted if you have soldered the board directly to the PCB.
At the end, you should have something similar to this:
5. Audio Power Options: The MAX98357 Audio Amplifier can be configured to have a gain of 3dB, 6dB, 9dB, 12dB, or 15dB. This is adjustable using the two solder jumpers on the PCB. The configuration is as follows:
- 15dB if JP2 OPEN and JP3 to 3
- 12dB if JP2 CLOSED and JP3 to 3
- 9dB if JP2 CLOSED
- 6dB if JP2 CLOSED and JP3 to 1
- 3dB if JP2 OPEN and JP3 to 1
If you plan to bridge the solder jumper JP2 (CLOSED), you can omit the 100K resistor at the R_GAIN position.
The steps to assemble the device casing are as follows:
1. 3D Print All Parts: Print the front and back panels, the switch and button extenders, and the button braille caps using a flexible material (e.g., TPU).
2. Prepare the Back Panel: Glue a piece of foam to the back panel and to the USB-C port of the ESP32. This will ensure that the board stays in place when a button is pressed and will position the camera at the correct angle.
3. Mount the PCB: Attach the PCB to the front panel. Add the switch battery extender (the white piece in the photo) and the battery/battery connector.
4. Assemble the Enclosure: Close the device by attaching the back panel and securing it with the five M3x20mm screws.
5. Install the Braille Button Caps: Mount the flexible braille button caps onto the button extenders.
6. Attach the Button Extensions: Snap the button extensions onto the device.
Note: You can add a strap or cord to the device to wear it around your neck. The battery is charged via the USB-C port on the ESP32.Code: "network_param.h":
All the parameters that need to be configured are in this file. Below, each of them is explained:
1. SSID and Password: This your network name and password, for this device to work you will need internet connection or data.
2. chatgpt_token: The device uses both ChatGPT for the image I.A processing and for the audio, for doing these you will need to follow these steps:
*Note: copy your API Key and store it somewhere safe. You will not be able to view it again.
It's practical to implement usage limits to manage your monthly spend on the API. In both audio uses and GPT-4o I have spend about 3.5$ so with a regular use it should be less than 10$/month.
3. root_ca: This is the certificate for Googles API Speech-to-Text, for generating it execute: openssl s_client -showcerts -connect speech.googleapis.com:443
4.ApiKey: This is the key for Googles API Speech-to-Text, follow this tutorial:
Future DevelopmentFor future versions, the following improvements could be included:
1.Make it smaller: The custom PCB is already designed to allow the ESP32 to be soldered in SMD, which would significantly reduce its size. To further minimize the device, a rechargeable 3.7V coin cell battery and a smaller speaker could be used. However, this would likely reduce the device's battery life, so the trade-off between size reduction and battery life would need to be carefully evaluated.
2.Faster responses: Currently, the device uses three AI APIs for processing audio and images: one for converting audio to text, one for analyzing photos/questions, and one for generating the output voice for the speaker.
To speed things up, integrating an embedded AI for handling both input (microphone) and output (speaker) audio would significantly reduce response times, as it would reduce reliance on external applications.
#include "network_param.h"
#include "AudioMic.h"
#include "CloudSpeechClient.h"
#include "Audio.h"
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <ChatGPT.hpp>
#include "Base64ImageData.h"
#include "esp_camera.h"
#include "SPIFFS.h"
#include <WiFi.h>
#include "base64.h"
#include "CameraConfig.h"
// AUDIO I2S PIN OUTPUT
#define I2S_LRC D3
#define I2S_DOUT D1
#define I2S_BCLK D2
#define I2S_MCLK 0
Audio audio(false, 3, 1); // USE I2S 1 (I2S0 FOR MICROPHONE AS I2S_MODE_PDM IS ONLY IN PIN I2S0)
WiFiClientSecure client_audio;
ChatGPT<WiFiClientSecure> chatGPT_Client(&client_audio, "v1", chatgpt_token, 60000);
// Variables for buttons
int button_pressed_camera = 0;
int button_pressed_microphone = 0;
const int button_camera = D8;
const int button_microphone = D9;
// Variable for audio transcript
String audio_transcript;
// Variables for camera
const char *photoPath = "/photo.jpg"; // File path for the photo
const char *base64ImageDataChar = nullptr;
void button_camera_trigger() {
if (button_pressed_camera == 0) {
button_pressed_camera = 1;
}
}
void button_microphone_trigger() {
if (button_pressed_microphone == 0) {
button_pressed_microphone = 1;
}
}
void capturePhoto() {
camera_fb_t *photo = esp_camera_fb_get();
if (!photo) {
Serial.println("Error capturing photo");
return;
}
// Save the photo in SPIFFS
File photoFile = SPIFFS.open(photoPath, FILE_WRITE);
if (!photoFile) {
Serial.println("Error opening file for writing");
return;
}
photoFile.write(photo->buf, photo->len);
photoFile.close();
Serial.println("Photo saved at: " + String(photoPath));
esp_camera_fb_return(photo);
//verifyImage(photoPath);
}
void verifyImage(const char *filePath) {
File file = SPIFFS.open(filePath, FILE_READ);
if (!file) {
Serial.println("Error opening file for reading");
return;
}
size_t fileSize = file.size();
uint8_t *buffer = new uint8_t[fileSize];
file.read(buffer, fileSize);
file.close();
String base64Data = base64::encode(buffer, fileSize);
delete[] buffer;
Serial.println("Image saved in Base64:\n");
Serial.println(base64Data);
// Optimized creation of base64DataWithPrefix
String base64DataWithPrefix = "data:image/jpeg;base64," + base64Data;
base64ImageDataChar = base64DataWithPrefix.c_str();
/* String result;
Serial.println("\n\n[ChatGPT] - Asking a Vision Question");
if (chatGPT_Client.vision_question("gpt-4o", "user", "text", "Whats in this image?", "image_url", base64ImageDataChar, "auto", 500, true, result)) {
Serial.print("[ChatGPT] Response: ");
Serial.println(result);
} else {
Serial.print("[ChatGPT] Error: ");
Serial.println(result);
}
Serial.println("END");*/
}
void ChatGPT_Vision(const String& question) {
/*
model: Model to use for generating the response (e.g., "gpt-4o").
role: Role of the message sender (e.g., "user" or "assistant").
type: Type of content (e.g., "text").
text: Text content of the message.
image_type: Type of the image (e.g., "image_url").
image_url: URL of the image or Base64 Image Data
detail: Detail level of the image (e.g., "high", "low", "auto").
max_tokens: Maximum number of tokens to generate in the response.
content_only: Flag indicating whether to extract only the content of the response. (e.g., true - answer only, false - full response)
result: Reference to a String variable to store the result of the API call.
*/
String result;
Serial.println("\n\n[ChatGPT] - Asking a Vision Question");
if (chatGPT_Client.vision_question("gpt-4o", "user", "text", question.c_str(), "image_url", base64ImageDataChar, "auto", 500, true, result)) {
Serial.print("[ChatGPT] Response: ");
Serial.println(result);
audio.openai_speech(chatgpt_token, "tts-1", result, "shimmer", "mp3", "1");
} else {
Serial.print("[ChatGPT] Error: ");
Serial.println(result);
}
}
void setup() {
Serial.begin(115200);
//Serial.setDebugOutput(true);
//while(!Serial);
Serial.println("START");
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(1500);
// BUTTONS
pinMode(button_camera, INPUT);
attachInterrupt(digitalPinToInterrupt(button_camera), button_camera_trigger, FALLING);
pinMode(button_microphone, INPUT);
attachInterrupt(digitalPinToInterrupt(button_microphone), button_microphone_trigger, FALLING);
// Audio
audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT, -1);
audio.setVolume(7);
client_audio.setInsecure();
// CAMERA
camera_config_t config = getCameraConfig();
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Error initializing the camera: 0x%x", err);
audio.connecttospeech("ERROR CAMERA", "en");
return;
}
// Mount the SPIFFS file system
if (!SPIFFS.begin(true)) {
Serial.println("Error mounting SPIFFS");
audio.connecttospeech("ERROR SPIFFS", "en");
return;
}
Serial.println("Camera ready");
//audio.connecttospeech("CAMERA READY", "en");
// CHATGPT CLIENT
}
void loop() {
// Main code here, to run repeatedly:
if (button_pressed_camera == 1) {
capturePhoto();
button_pressed_camera = 0;
} else if (button_pressed_microphone == 1) {
verifyImage(photoPath);
//Serial.println(base64ImageDataChar);
Serial.println("\r\nRecord start!\r\n");
AudioMic* audio_Mic = new AudioMic(SENSE);
audio_Mic->Record();
Serial.println("Recording Completed. Now Processing...");
//audio.connecttospeech("RECORD FINISH", "en");
CloudSpeechClient* cloudSpeechClient = new CloudSpeechClient(USE_APIKEY);
cloudSpeechClient->Transcribe(audio_Mic);
Serial.print("Transcript: ");
Serial.println(transcript);
//audio.connecttospeech("TRANSCRIPT", "en");
audio_transcript = String(transcript);
delete cloudSpeechClient;
delete audio_Mic;
Serial.print("Transcript AUDIO: ");
Serial.println(audio_transcript);
//audio.connecttospeech(transcript, "es");
button_pressed_microphone = 0;
ChatGPT_Vision(audio_transcript);
}
audio.loop();
}
void audio_info(const char *info) {
Serial.print("audio_info: "); Serial.println(info);
if (strcmp(info, "End of Stream.") == 0) {
Serial.println("FINISH");
esp_restart();
}
}
#ifndef _NETWORK_PARAM_H
#define _NETWORK_PARAM_H
inline const char *ssid = "ssid";
inline const char *password = "password";
inline const char* server = "speech.googleapis.com";
inline const char* chatgpt_token = "your-api-key";//CHATGPT API KEY
// To get the certificate for your region run:
// openssl s_client -showcerts -connect speech.googleapis.com:443
// Copy the certificate (all lines between and including ---BEGIN CERTIFICATE---
// and --END CERTIFICATE--) to root.cert and put here on the root_cert variable.
inline const char* root_ca=
"-----BEGIN CERTIFICATE-----\n"
"MIIFCzCCAvOgAwIBAgIQf/AFoHxM3tEArZ1mpRB7mDANBgkqhkiG9w0BAQsFADBH\n"
"MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\n"
"QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjMxMjEzMDkwMDAwWhcNMjkwMjIw\n"
"MTQwMDAwWjA7MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNl\n"
"cnZpY2VzMQwwCgYDVQQDEwNXUjIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n"
"AoIBAQCp/5x/RR5wqFOfytnlDd5GV1d9vI+aWqxG8YSau5HbyfsvAfuSCQAWXqAc\n"
"+MGr+XgvSszYhaLYWTwO0xj7sfUkDSbutltkdnwUxy96zqhMt/TZCPzfhyM1IKji\n"
"aeKMTj+xWfpgoh6zySBTGYLKNlNtYE3pAJH8do1cCA8Kwtzxc2vFE24KT3rC8gIc\n"
"LrRjg9ox9i11MLL7q8Ju26nADrn5Z9TDJVd06wW06Y613ijNzHoU5HEDy01hLmFX\n"
"xRmpC5iEGuh5KdmyjS//V2pm4M6rlagplmNwEmceOuHbsCFx13ye/aoXbv4r+zgX\n"
"FNFmp6+atXDMyGOBOozAKql2N87jAgMBAAGjgf4wgfswDgYDVR0PAQH/BAQDAgGG\n"
"MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/\n"
"AgEAMB0GA1UdDgQWBBTeGx7teRXUPjckwyG77DQ5bUKyMDAfBgNVHSMEGDAWgBTk\n"
"rysmcRorSCeFL1JmLO/wiRNxPjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAKG\n"
"GGh0dHA6Ly9pLnBraS5nb29nL3IxLmNydDArBgNVHR8EJDAiMCCgHqAchhpodHRw\n"
"Oi8vYy5wa2kuZ29vZy9yL3IxLmNybDATBgNVHSAEDDAKMAgGBmeBDAECATANBgkq\n"
"hkiG9w0BAQsFAAOCAgEARXWL5R87RBOWGqtY8TXJbz3S0DNKhjO6V1FP7sQ02hYS\n"
"TL8Tnw3UVOlIecAwPJQl8hr0ujKUtjNyC4XuCRElNJThb0Lbgpt7fyqaqf9/qdLe\n"
"SiDLs/sDA7j4BwXaWZIvGEaYzq9yviQmsR4ATb0IrZNBRAq7x9UBhb+TV+PfdBJT\n"
"DhEl05vc3ssnbrPCuTNiOcLgNeFbpwkuGcuRKnZc8d/KI4RApW//mkHgte8y0YWu\n"
"ryUJ8GLFbsLIbjL9uNrizkqRSvOFVU6xddZIMy9vhNkSXJ/UcZhjJY1pXAprffJB\n"
"vei7j+Qi151lRehMCofa6WBmiA4fx+FOVsV2/7R6V2nyAiIJJkEd2nSi5SnzxJrl\n"
"Xdaqev3htytmOPvoKWa676ATL/hzfvDaQBEcXd2Ppvy+275W+DKcH0FBbX62xevG\n"
"iza3F4ydzxl6NJ8hk8R+dDXSqv1MbRT1ybB5W0k8878XSOjvmiYTDIfyc9acxVJr\n"
"Y/cykHipa+te1pOhv7wYPYtZ9orGBV5SGOJm4NrB3K1aJar0RfzxC3ikr7Dyc6Qw\n"
"qDTBU39CluVIQeuQRgwG3MuSxl7zRERDRilGoKb8uY45JzmxWuKxrfwT/478JuHU\n"
"/oTxUFqOl2stKnn7QGTq8z29W+GgBLCXSBxC9epaHM0myFH/FJlniXJfHeytWt0=\n"
"-----END CERTIFICATE-----\n";
// Getting Access Token :
// At first, you should get service account key (JSON file).
// Type below command in Google Cloud Shell to get AccessToken:
// $ gcloud auth activate-service-account --key-file=KEY_FILE (KEY_FILE is your service account key file)
// $ gcloud auth print-access-token
// The Access Token is expired in an hour.
// Google recommends to use Access Token.
//const String AccessToken = "";
// It is also possible to use "API Key" instead of "Access Token". It doesn't have time limit.
inline const String ApiKey = "Googles Speech To Texy Api Key";
// see https://cloud.google.com/docs/authentication?hl=ja#getting_credentials_for_server-centric_flow
// see https://qiita.com/basi/items/3623a576b754f738138e (Japanese)
#endif // _NETWORK_PARAM_H
#include "AudioMic.h"
AudioMic::AudioMic(MicType micType) {
wavData = new char*[wavDataSize/dividedWavDataSize];
for (int i = 0; i < wavDataSize/dividedWavDataSize; ++i) wavData[i] = new char[dividedWavDataSize];
i2s = new I2S(micType);
}
AudioMic::~AudioMic() {
for (int i = 0; i < wavDataSize/dividedWavDataSize; ++i) delete[] wavData[i];
delete[] wavData;
delete i2s;
}
void AudioMic::CreateWavHeader(byte* header, int waveDataSize){
header[0] = 'R';
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
unsigned int fileSizeMinus8 = waveDataSize + 44 - 8;
header[4] = (byte)(fileSizeMinus8 & 0xFF);
header[5] = (byte)((fileSizeMinus8 >> 8) & 0xFF);
header[6] = (byte)((fileSizeMinus8 >> 16) & 0xFF);
header[7] = (byte)((fileSizeMinus8 >> 24) & 0xFF);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f';
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 0x10; // linear PCM
header[17] = 0x00;
header[18] = 0x00;
header[19] = 0x00;
header[20] = 0x01; // linear PCM
header[21] = 0x00;
header[22] = 0x01; // monoral
header[23] = 0x00;
header[24] = 0x80; // sampling rate 16000
header[25] = 0x3E;
header[26] = 0x00;
header[27] = 0x00;
header[28] = 0x00; // Byte/sec = 16000x2x1 = 32000
header[29] = 0x7D;
header[30] = 0x00;
header[31] = 0x00;
header[32] = 0x02; // 16bit monoral
header[33] = 0x00;
header[34] = 0x10; // 16bit
header[35] = 0x00;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte)(waveDataSize & 0xFF);
header[41] = (byte)((waveDataSize >> 8) & 0xFF);
header[42] = (byte)((waveDataSize >> 16) & 0xFF);
header[43] = (byte)((waveDataSize >> 24) & 0xFF);
}
void AudioMic::Record() {
CreateWavHeader(paddedHeader, wavDataSize);
int bitBitPerSample = i2s->GetBitPerSample();
if (bitBitPerSample == 16) {
for (int j = 0; j < wavDataSize/dividedWavDataSize; ++j) {
i2s->Read(i2sBuffer, i2sBufferSize/2);
for (int i = 0; i < i2sBufferSize/8; ++i) {
wavData[j][2*i] = i2sBuffer[4*i + 2];
wavData[j][2*i + 1] = i2sBuffer[4*i + 3];
}
}
}
else if (bitBitPerSample == 32) {
for (int j = 0; j < wavDataSize/dividedWavDataSize; ++j) {
i2s->Read(i2sBuffer, i2sBufferSize);
for (int i = 0; i < i2sBufferSize/8; ++i) {
wavData[j][2*i] = i2sBuffer[8*i + 2];
wavData[j][2*i + 1] = i2sBuffer[8*i + 3];
}
}
}
}
#ifndef _AUDIOMIC_H
#define _AUDIOMIC_H
#include <Arduino.h>
#include "I2S.h"
// 16bit, monoral, 16000Hz, linear PCM
class AudioMic {
I2S* i2s;
static const int headerSize = 44;
static const int i2sBufferSize = 12000;
char i2sBuffer[i2sBufferSize];
void CreateWavHeader(byte* header, int waveDataSize);
public:
static const int wavDataSize = 90000; // It must be multiple of dividedWavDataSize. Recording time is about 1.9 second.
static const int dividedWavDataSize = i2sBufferSize/4;
char** wavData; // It's divided. Because large continuous memory area can't be allocated in esp32.
byte paddedHeader[headerSize + 4] = {0}; // The size must be multiple of 3 for Base64 encoding. Additional byte size must be even because wave data is 16bit.
AudioMic(MicType micType);
~AudioMic();
void Record();
};
#endif // _AUDIO_H
#ifndef BASE64_IMAGE_DATA_H
#define BASE64_IMAGE_DATA_H
// The image is an orange cat :).
const char* base64ImageData = "data:image/jpeg;base64,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lgkc4Vio9qrTWkytg7ZN394c01qTcqvHGgIeEqV6ADrUT7pFCBSiDrnqaaBu5Q1IRx2xG7k8DbXNRjA+Y85pjiWVAc5FSbCOtK5VjtzNgYzgewpFnRiVy5A67hgV47PTRF56R5wGOP7qgCq8lxk7sszHjH+H/wBasb9DRIs2sD5BcbWxkj+6K3bIBQfuoh/iP+cmuilF3MakjYs328Mx2Z43Hk1cBR24OPYV6VKzVjhqdy8oi2bV6fzqhcxYJweK2aMUzPmX5l3fdHQVTmJyRjisxlYr6dqaV+bFNEMryxKeSOSartGMdvpVoVzI1iJGtyCOR7VzX2Ubs0pbmsNh4g2dDQWIBzUFnWrPGg5ReOmMVHLettxHGx+pwK8qT00PQS1KrPJIp3Msag5OOadC8VuvmBWZ+ilxz9ay8zS+li5HcFwuPmkY9SeF9/rVyGXy2VyxbGeTxit6ZjM2bW+UpvAH+z6D3q3bzZPmB+vGTXZTfvI5ZLRmpFMvUHI9fWpXZWXuc12M5CpJCOSRn2qi9vu+Y8bug9qloLleRVjXYo+Y8VUlJEi4555oSE2VpjkEZIxzVd2O0ZwatIRkagxOVzwfaszyxnNRNamsHoRSLgdOtV5IW28c1Ni7n//ZAP/tFPBQaG90b3Nob3AgMy4wADhCSU0EJQAAAAAAEAAAAAAAAAAAAAAAAAAAAAA4QklNA+0AAAAAABAASAAAAAEAAgBIAAAAAQACOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD+AAAA4QklNBA0AAAAAAAQAAAB4OEJJTQQZAAAAAAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNBAoAAAAAAAEAADhCSU0nEAAAAAAACgABAAAAAAAAAAI4QklNA/UAAAAAAEgAL2ZmAAEAbGZmAAYAAAAAAAEAL2ZmAAEAoZmaAAYAAAAAAAEAMgAAAAEAWgAAAAYAAAAAAAEANQAAAAEALQAAAAYAAAAAAAE4QklNA/gAAAAAAHAAAP////////////////////////////8D6AAAAAD/////////////////////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////////////////////8D6AAAOEJJTQQIAAAAAAAQAAAAAQAAAkAAAAJA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RGltZW5zaW9uPjI0MDA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPg0KCQkJPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjE3ODQ8L2V4aWY6UGl4ZWxZRGltZW5zaW9uPg0KCQk8L3JkZjpEZXNjcmlwdGlvbj4NCgkJPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9InV1aWQ6MmIzYmI5NzEtNTc4OC0xMWUzLTlhMDUtODg1OTA0Y2Y1NmIwIiB4bWxuczpwZGY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGRmLzEuMy8iPg0KCQk8L3JkZjpEZXNjcmlwdGlvbj4NCgkJPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9InV1aWQ6MmIzYmI5NzEtNTc4OC0xMWUzLTlhMDUtODg1OTA0Y2Y1NmIwIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iPg0KCQkJPHBob3Rvc2hvcDpIaXN0b3J5PjwvcGhvdG9zaG9wOkhpc3Rvcnk+DQoJCTwvcmRmOkRlc2NyaXB0aW9uPg0KCQk8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0idXVpZDoyYjNiYjk3MS01Nzg4LTExZTMtOWEwNS04ODU5MDRjZjU2YjAiIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIj4NCgkJCTx0aWZmOlhSZXNvbHV0aW9uPjcyLzE8L3RpZmY6WFJlc29sdXRpb24+DQoJCQk8dGlmZjpZUmVzb2x1dGlvbj43Mi8xPC90aWZmOllSZXNvbHV0aW9uPg0KCQkJPHRpZmY6UmVzb2x1dGlvblVuaXQ+MjwvdGlmZjpSZXNvbHV0aW9uVW5pdD4NCgkJPC9yZGY6RGVzY3JpcHRpb24+DQoJCTxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSJ1dWlkOjJiM2JiOTcxLTU3ODgtMTFlMy05YTA1LTg4NTkwNGNmNTZiMCIgeG1sbnM6eGFwPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIj4NCgkJCTx4YXA6Q3JlYXRlRGF0ZT4yMDEzLTExLTI3VDE1OjIwOjEwLTAzOjAwPC94YXA6Q3JlYXRlRGF0ZT4NCgkJCTx4YXA6TW9kaWZ5RGF0ZT4yMDEzLTExLTI3VDE1OjIwOjQ1LTAzOjAwPC94YXA6TW9kaWZ5RGF0ZT4NCgkJCTx4YXA6TWV0YWRhdGFEYXRlPjIwMTMtMTEtMjdUMTU6MjA6NDUtMDM6MDA8L3hhcDpNZXRhZGF0YURhdGU+DQoJCQk8eGFwOkNyZWF0b3JUb29sPkFkb2JlIFBob3Rvc2hvcCBDUyBXaW5kb3dzPC94YXA6Q3JlYXRvclRvb2w+DQoJCTwvcmRmOkRlc2NyaXB0aW9uPg0KCQk8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0idXVpZDoyYjNiYjk3MS01Nzg4LTExZTMtOWEwNS04ODU5MDRjZjU2YjAiIHhtbG5zOnhhcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIj4NCgkJCTx4YXBNTTpEb2N1bWVudElEPmFkb2JlOmRvY2lkOnBob3Rvc2hvcDpmZTVhNTU0YS01Nzg3LTExZTMtOWEwNS04ODU5MDRjZjU2YjA8L3hhcE1NOkRvY3VtZW50SUQ+DQoJCTwvcmRmOkRlc2NyaXB0aW9uPg0KCQk8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0idXVpZDoyYjNiYjk3MS01Nzg4LTExZTMtOWEwNS04ODU5MDRjZjU2YjAiIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+DQoJCQk8ZGM6Zm9ybWF0PmltYWdlL2pwZWc8L2RjOmZvcm1hdD4NCgkJPC9yZGY6RGVzY3JpcHRpb24+DQoJPC9yZGY6UkRGPg0KPC94OnhtcG1ldGE+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQgZW5kPSd3Jz8+/+ICQElDQ19QUk9GSUxFAAEBAAACMEFEQkUCEAAAbW50clJHQiBYWVogB88ABgADAAAAAAAAYWNzcEFQUEwAAAAAbm9uZQAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAAA0y1BREJFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKY3BydAAAAPwAAAAyZGVzYwAAATAAAABrd3RwdAAAAZwAAAAUYmtwdAAAAbAAAAAUclRSQwAAAcQAAAAOZ1RSQwAAAdQAAAAOYlRSQwAAAeQAAAAOclhZWgAAAfQAAAAUZ1hZWgAAAggAAAAUYlhZWgAAAhwAAAAUdGV4dAAAAABDb3B5cmlnaHQgMTk5OSBBZG9iZSBTeXN0ZW1zIEluY29ycG9yYXRlZAAAAGRlc2MAAAAAAAAAEUFkb2JlIFJHQiAoMTk5OCkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAAARbMWFlaIAAAAAAAAAAAAAAAAAAAAABjdXJ2AAAAAAAAAAECMwAAY3VydgAAAAAAAAABAjMAAGN1cnYAAAAAAAAAAQIzAABYWVogAAAAAAAAnBgAAE+lAAAE/FhZWiAAAAAAAAA0jQAAoCwAAA+VWFlaIAAAAAAAACYxAAAQLwAAvpz/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMF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";
#endif
#if defined(CAMERA_MODEL_WROVER_KIT)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 21
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 19
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 5
#define Y2_GPIO_NUM 4
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
#elif defined(CAMERA_MODEL_ESP_EYE)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 4
#define SIOD_GPIO_NUM 18
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 36
#define Y8_GPIO_NUM 37
#define Y7_GPIO_NUM 38
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 35
#define Y4_GPIO_NUM 14
#define Y3_GPIO_NUM 13
#define Y2_GPIO_NUM 34
#define VSYNC_GPIO_NUM 5
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 25
#define LED_GPIO_NUM 22
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 22
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_WIDE)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 22
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#define LED_GPIO_NUM 2
#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 17
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_UNITCAM)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 32
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_M5STACK_CAMS3_UNIT)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM 21
#define XCLK_GPIO_NUM 11
#define SIOD_GPIO_NUM 17
#define SIOC_GPIO_NUM 41
#define Y9_GPIO_NUM 13
#define Y8_GPIO_NUM 4
#define Y7_GPIO_NUM 10
#define Y6_GPIO_NUM 5
#define Y5_GPIO_NUM 7
#define Y4_GPIO_NUM 16
#define Y3_GPIO_NUM 15
#define Y2_GPIO_NUM 6
#define VSYNC_GPIO_NUM 42
#define HREF_GPIO_NUM 18
#define PCLK_GPIO_NUM 12
#define LED_GPIO_NUM 14
#elif defined(CAMERA_MODEL_AI_THINKER)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
// 4 for flash led or 33 for normal led
#define LED_GPIO_NUM 4
#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL)
#define PWDN_GPIO_NUM 0
#define RESET_GPIO_NUM 15
#define XCLK_GPIO_NUM 27
#define SIOD_GPIO_NUM 25
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 19
#define Y8_GPIO_NUM 36
#define Y7_GPIO_NUM 18
#define Y6_GPIO_NUM 39
#define Y5_GPIO_NUM 5
#define Y4_GPIO_NUM 34
#define Y3_GPIO_NUM 35
#define Y2_GPIO_NUM 17
#define VSYNC_GPIO_NUM 22
#define HREF_GPIO_NUM 26
#define PCLK_GPIO_NUM 21
#elif defined(CAMERA_MODEL_XIAO_ESP32S3)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 10
#define SIOD_GPIO_NUM 40
#define SIOC_GPIO_NUM 39
#define Y9_GPIO_NUM 48
#define Y8_GPIO_NUM 11
#define Y7_GPIO_NUM 12
#define Y6_GPIO_NUM 14
#define Y5_GPIO_NUM 16
#define Y4_GPIO_NUM 18
#define Y3_GPIO_NUM 17
#define Y2_GPIO_NUM 15
#define VSYNC_GPIO_NUM 38
#define HREF_GPIO_NUM 47
#define PCLK_GPIO_NUM 13
#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD)
// The 18 pin header on the board has Y5 and Y3 swapped
#define USE_BOARD_HEADER 0
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM 33
#define XCLK_GPIO_NUM 4
#define SIOD_GPIO_NUM 18
#define SIOC_GPIO_NUM 23
#define Y9_GPIO_NUM 36
#define Y8_GPIO_NUM 19
#define Y7_GPIO_NUM 21
#define Y6_GPIO_NUM 39
#if USE_BOARD_HEADER
#define Y5_GPIO_NUM 13
#else
#define Y5_GPIO_NUM 35
#endif
#define Y4_GPIO_NUM 14
#if USE_BOARD_HEADER
#define Y3_GPIO_NUM 35
#else
#define Y3_GPIO_NUM 13
#endif
#define Y2_GPIO_NUM 34
#define VSYNC_GPIO_NUM 5
#define HREF_GPIO_NUM 27
#define PCLK_GPIO_NUM 25
#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 40
#define SIOD_GPIO_NUM 17
#define SIOC_GPIO_NUM 18
#define Y9_GPIO_NUM 39
#define Y8_GPIO_NUM 41
#define Y7_GPIO_NUM 42
#define Y6_GPIO_NUM 12
#define Y5_GPIO_NUM 3
#define Y4_GPIO_NUM 14
#define Y3_GPIO_NUM 47
#define Y2_GPIO_NUM 13
#define VSYNC_GPIO_NUM 21
#define HREF_GPIO_NUM 38
#define PCLK_GPIO_NUM 11
#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD)
// The 18 pin header on the board has Y5 and Y3 swapped
#define USE_BOARD_HEADER 0
#define PWDN_GPIO_NUM 1
#define RESET_GPIO_NUM 2
#define XCLK_GPIO_NUM 42
#define SIOD_GPIO_NUM 41
#define SIOC_GPIO_NUM 18
#define Y9_GPIO_NUM 16
#define Y8_GPIO_NUM 39
#define Y7_GPIO_NUM 40
#define Y6_GPIO_NUM 15
#if USE_BOARD_HEADER
#define Y5_GPIO_NUM 12
#else
#define Y5_GPIO_NUM 13
#endif
#define Y4_GPIO_NUM 5
#if USE_BOARD_HEADER
#define Y3_GPIO_NUM 13
#else
#define Y3_GPIO_NUM 12
#endif
#define Y2_GPIO_NUM 14
#define VSYNC_GPIO_NUM 38
#define HREF_GPIO_NUM 4
#define PCLK_GPIO_NUM 3
#elif defined(CAMERA_MODEL_ESP32S3_EYE)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 15
#define SIOD_GPIO_NUM 4
#define SIOC_GPIO_NUM 5
#define Y2_GPIO_NUM 11
#define Y3_GPIO_NUM 9
#define Y4_GPIO_NUM 8
#define Y5_GPIO_NUM 10
#define Y6_GPIO_NUM 12
#define Y7_GPIO_NUM 18
#define Y8_GPIO_NUM 17
#define Y9_GPIO_NUM 16
#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM 7
#define PCLK_GPIO_NUM 13
#elif defined(CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3) || defined(CAMERA_MODEL_DFRobot_Romeo_ESP32S3)
#define PWDN_GPIO_NUM -1
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 45
#define SIOD_GPIO_NUM 1
#define SIOC_GPIO_NUM 2
#define Y9_GPIO_NUM 48
#define Y8_GPIO_NUM 46
#define Y7_GPIO_NUM 8
#define Y6_GPIO_NUM 7
#define Y5_GPIO_NUM 4
#define Y4_GPIO_NUM 41
#define Y3_GPIO_NUM 40
#define Y2_GPIO_NUM 39
#define VSYNC_GPIO_NUM 6
#define HREF_GPIO_NUM 42
#define PCLK_GPIO_NUM 5
#else
#error "Camera model not selected"
#endif
// CameraConfig.cpp
#include "CameraConfig.h"
#include "esp_camera.h" // Para el tipo `camera_config_t` y funciones de la cmara
camera_config_t getCameraConfig() {
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sccb_sda = SIOD_GPIO_NUM;
config.pin_sccb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG; // for streaming
config.grab_mode = CAMERA_GRAB_LATEST;
config.fb_location = CAMERA_FB_IN_PSRAM;
config.jpeg_quality = 5;
config.fb_count = 2;
config.frame_size = FRAMESIZE_VGA;
if (config.pixel_format == PIXFORMAT_JPEG) {
if (psramFound()) {
// Additional PSRAM configurations (if needed)
} else {
config.frame_size = FRAMESIZE_SVGA;
config.fb_location = CAMERA_FB_IN_DRAM;
}
} else {
config.frame_size = FRAMESIZE_240X240;
}
#if defined(CAMERA_MODEL_XIAO_ESP32S3)
pinMode(13, INPUT_PULLUP);
pinMode(14, INPUT_PULLUP);
#endif
return config;
}
#ifndef _CLOUDSPEECHCLIENT_H
#define _CLOUDSPEECHCLIENT_H
#include <WiFiClientSecure.h>
#include "AudioMic.h"
extern const char* transcript;
enum Authentication {
USE_ACCESSTOKEN,
USE_APIKEY
};
class CloudSpeechClient {
WiFiClientSecure client;
void PrintHttpBody2(AudioMic* audio_Mic);
Authentication authentication;
public:
CloudSpeechClient(Authentication authentication);
~CloudSpeechClient();
void Transcribe(AudioMic* audio_Mic);
void client_stop();
void client_begin();
};
#endif // _CLOUDSPEECHCLIENT_H
#include "I2S.h"
#define SAMPLE_RATE (16000)
#define PIN_I2S_BCLK 26
#define PIN_I2S_LRC 22
#define PIN_I2S_DIN 34
#define PIN_I2S_DOUT 25
#define I2S_PORT I2S_NUM_0
// This I2S specification :
// - LRC high is channel 2 (right).
// - LRC signal transitions once each word.
// - DATA is valid on the CLOCK rising edge.
// - Data bits are MSB first.
// - DATA bits are left-aligned with respect to LRC edge.
// - DATA bits are right-shifted by one with respect to LRC edges.
I2S::I2S(MicType micType) {
if (micType == SENSE) {
BITS_PER_SAMPLE = I2S_BITS_PER_SAMPLE_16BIT;
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM ),
.sample_rate = 16000U,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT, // Also works
//.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_PCM, // Also works
//.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 1024,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
i2s_pin_config_t i2s_mic_pins = {
.bck_io_num = I2S_PIN_NO_CHANGE,
.ws_io_num = 42,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = 41
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
i2s_set_pin(I2S_PORT, &i2s_mic_pins);
i2s_set_clk(I2S_PORT, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_STEREO);
}
}
int I2S::Read(char* data, int numData) {
size_t bytes_read = 0;
esp_err_t result = i2s_read(I2S_PORT, (void *)data, numData, &bytes_read, portMAX_DELAY);
if (result == ESP_OK) {
return bytes_read;
} else {
Serial.print("Error reading I2S data: ");
Serial.println(result);
return 0;
}
}
int I2S::GetBitPerSample() {
return (int)BITS_PER_SAMPLE;
}
#ifndef _I2S_H
#define _I2S_H
#include <Arduino.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2s.h"
#include "esp_system.h"
enum MicType {
ADMP441,
ICS43434,
M5GO,
M5STACKFIRE,
SENSE
};
class I2S {
i2s_bits_per_sample_t BITS_PER_SAMPLE;
public:
I2S(MicType micType);
int Read(char* data, int numData);
int GetBitPerSample();
};
#endif // _I2S_H
Comments