
This is a getting started guide for the TTGO T-Journal ESP32 Camera Development Board. The TTGO T-Journal features an OV2640 camera, an OLED display, several GPIOs to connect peripherals and a built-in programmer, which makes it easy to upload code. We’ll take a quick look at the camera dev board and learn how to program it using Arduino IDE.
Introducing the TTGO T-Journal ESP32 Camera
The TTGO T-Journal is an ESP32 Camera Development Board with an OV2640 camera, an antenna, an I2C SSD1306 0.91 inch OLED display, some exposed GPIOs, and a micro-USB interface that makes it easy and quick to upload code to the board.
TTGO T-Journal ESP32 Features
Here’s a summary of the TTGO T-Journal features:
- Chipset ESPRESSIF-ESP32-PCIO-D4 240MHz Xtensa® single-/dual-core 32-bit LX6 microprocessor
- FLASH QSPI flash/SRAM, up to 4 x 16 MBSRAM 520 kB SRAM
- Reset button and button on GPIO 32
- 0.91 inch SSD1306 OLED display
- Power indicator red LED
- USB to TTL CP2104 (you can upload code via USB cable);
- Camera OV2640 2 Megapixel
- Steering engine analog servo (comes with two sets of pins ideal to connect servos)
- Working voltage: 2.3V-3.6V
- Working current: about 160mA
- Size: 64.57mm x 23.98mm
Power supply specifications:
- Power Supply USB 5V/1A
- Charging current 1A
- Battery 3.7V lithium battery
TTGO T-Journal ESP32 Board Pinout
Having the right pinout for your camera board is very important. If you don’t assign the right camera pins in your code, the camera will not work. The following image shows the TTGO T-Journal ESP32 board pinout.
TTGO T-Journal ESP32 Camera Connections

Here’s a table with the connections between the ESP32 and the camera:
OV2640 Camera | ESP32 |
D2 | GPIO 17 |
D3 | GPIO 35 |
D4 | GPIO 34 |
D5 | GPIO 5 |
D6 | GPIO 39 |
D7 | GPIO 18 |
D8 | GPIO 36 |
D9 | GPIO 19 |
SIOC | GPIO 23 |
SIOD | GPIO 25 |
XCLK | GPIO 27 |
VSYNC | GPIO 22 |
HREF | GPIO 26 |
PCLK | GPIO 21 |
RST | GPIO 15 |
PWDN | GPIO 0 |
So, the pin assignment in your Arduino sketch should be as follows:
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#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
Because this board uses the same camera used in the ESP32-CAM board, the examples for the ESP32-CAM (that don’t use microSD card) should also work with the TTGO T-Journal by changing the pin definition. We’ll show you a couple of examples in a moment.
TTGO T-Journal ESP32 Board OLED Connections

This board comes with an I2C SSD1306 0.91 inch OLED display. To interact with the display you can use the Adafruit SSD1306, the oled-ssd1306 or other compatible libraries. We usually use the Adafruit SSD1306 along with the Adafruit_GFX to interact with OLED displays.
The OLED communicates with the ESP32 using the following pins:
OLED | ESP32 |
SDA | GPIO 14 |
SCL | GPIO 13 |
TTGO T-Journal ESP32 Board Control OLED Display
In this section, well show you quick tips on how to control the OLED display of the TTGO T-Journal ESP32 board.
Installing Libraries
To control the OLED display, we’ll use the Adafruit SSD1306 and Adafruit GFX libraries. These libraries can be installed through the Arduino IDE Library Manager.
In your Arduino IDE, go to Sketch > Include Library > Manage Libraries. Then, search for the library name and install it.
OLED I2C Pins and Display Size
Controlling this OLED display is similar to control a regular 0.96 OLED display connected to an ESP32. The only difference is the way you initialize the display.
You need to take into account the I2C pins used by this display (because it doesn’t use the default I2C pins), and the size of the display.
- I2C pins:
- SDA (GPIO 14)
- SCL (GPIO 13)
- Display size:
- Width: 128 px
- Height: 32 px
Arduino Sketch
To control the OLED display, first, you need to import the required libraries:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Define the OLED size:
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
Define the I2C pins:
#define I2C_SDA 14
#define I2C_SCL 13
Next create an Adafruit_SSD1306 object called display as follows:
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
In the setup(), you need to initialize an I2C communication on the I2C pins you’ve defined earlier as follows:
Wire.begin(I2C_SDA, I2C_SCL);
Then, initialize the OLED display as follows:
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
After properly initializing the display, you can use the usual functions to write text and display shapes on the OLED. Read our OLED tutorial with the ESP32 to learn more on how to interact with the OLED display.
For testing purposes, you can upload the following code to your board. It simply displays “Hello World”.
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/ttgo-t-journal-esp32-camera-getting-started/
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 <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define I2C_SDA 14
#define I2C_SCL 13
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Wire.begin(I2C_SDA, I2C_SCL);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Hello World!");;
display.display();
}
void loop() {
// put your main code here, to run repeatedly:
}

TTGO T-Journal ESP32 Camera Projects
We’ve modified some of our existing ESP32-CAM projects to be compatible with the TTGO T-Journal.
Video Streaming Web Server
The following code creates a video streaming web server on the camera IP address. So, you can create an IP CAM that can be integrated in Home Automation platforms like Home Assistant or Node-RED.
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/ttgo-t-journal-esp32-camera-getting-started/
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 "esp_camera.h"
#include <WiFi.h>
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "soc/soc.h" //disable brownout problems
#include "soc/rtc_cntl_reg.h" //disable brownout problems
#include "esp_http_server.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define I2C_SDA 14
#define I2C_SCL 13
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
#define PART_BOUNDARY "123456789000000000000987654321"
// OV2640 camera module pins (CAMERA_MODEL_TTGO-T-Journal)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#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
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
httpd_handle_t stream_httpd = NULL;
static esp_err_t stream_handler(httpd_req_t *req){
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
char * part_buf[64];
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if(res != ESP_OK){
return res;
}
while(true){
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
res = ESP_FAIL;
} else {
if(fb->width > 400){
if(fb->format != PIXFORMAT_JPEG){
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if(!jpeg_converted){
Serial.println("JPEG compression failed");
res = ESP_FAIL;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
}
}
if(res == ESP_OK){
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(fb){
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if(_jpg_buf){
free(_jpg_buf);
_jpg_buf = NULL;
}
if(res != ESP_OK){
break;
}
//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
}
return res;
}
void startCameraServer(){
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = stream_handler,
.user_ctx = NULL
};
//Serial.printf("Starting web server on port: '%d'\n", config.server_port);
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(stream_httpd, &index_uri);
}
}
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
Serial.setDebugOutput(false);
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_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_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;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
// Wi-Fi connection
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("Camera Stream Ready! Go to: http://");
Serial.print(WiFi.localIP());
// Init OLED
Wire.begin(I2C_SDA, I2C_SCL);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(5, 5);
display.print(WiFi.localIP());;
display.display();
// Start streaming web server
startCameraServer();
}
void loop() {
delay(1);
}

Learn more about this project: ESP32-CAM Video Streaming Web Server
Take Photo and Display in Web Server
The following code creates a web server that you can access to take and display photos. The web server IP address is displayed on the OLED.
/*
Rui Santos
Complete project details at https://RandomNerdTutorials.com/ttgo-t-journal-esp32-camera-getting-started/
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 "WiFi.h"
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour problems
#include "driver/rtc_io.h"
#include <ESPAsyncWebServer.h>
#include <StringArray.h>
#include <SPIFFS.h>
#include <FS.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define I2C_SDA 14
#define I2C_SCL 13
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
boolean takeNewPhoto = false;
// Photo File Name to save in SPIFFS
#define FILE_PHOTO "/photo.jpg"
// OV2640 camera module pins (CAMERA_MODEL_TTGO-T-Journal)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#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
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { text-align:center; }
.vert { margin-bottom: 10%; }
.hori{ margin-bottom: 0%; }
</style>
</head>
<body>
<div id="container">
<h2>ESP32-CAM Last Photo</h2>
<p>It might take more than 5 seconds to capture a photo.</p>
<p>
<button onclick="rotatePhoto();">ROTATE</button>
<button onclick="capturePhoto()">CAPTURE PHOTO</button>
<button onclick="location.reload();">REFRESH PAGE</button>
</p>
</div>
<div><img src="saved-photo" id="photo" width="70%"></div>
</body>
<script>
var deg = 0;
function capturePhoto() {
var xhr = new XMLHttpRequest();
xhr.open('GET', "/capture", true);
xhr.send();
}
function rotatePhoto() {
var img = document.getElementById("photo");
deg += 90;
if(isOdd(deg/90)){ document.getElementById("container").className = "vert"; }
else{ document.getElementById("container").className = "hori"; }
img.style.transform = "rotate(" + deg + "deg)";
}
function isOdd(n) { return Math.abs(n % 2) == 1; }
</script>
</html>)rawliteral";
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
ESP.restart();
}
else {
delay(500);
Serial.println("SPIFFS mounted successfully");
}
// Print ESP32 Local IP Address
Serial.print("IP Address: http://");
Serial.println(WiFi.localIP());
// Init OLED
Wire.begin(I2C_SDA, I2C_SCL);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(5, 5);
display.print(WiFi.localIP());;
display.display();
// Turn-off the 'brownout detector'
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// OV2640 camera module
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_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_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;
if (psramFound()) {
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
ESP.restart();
}
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html);
});
server.on("/capture", HTTP_GET, [](AsyncWebServerRequest * request) {
takeNewPhoto = true;
request->send_P(200, "text/plain", "Taking Photo");
});
server.on("/saved-photo", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send(SPIFFS, FILE_PHOTO, "image/jpg", false);
});
// Start server
server.begin();
}
void loop() {
if (takeNewPhoto) {
capturePhotoSaveSpiffs();
takeNewPhoto = false;
}
delay(1);
}
// Check if photo capture was successful
bool checkPhoto( fs::FS &fs ) {
File f_pic = fs.open( FILE_PHOTO );
unsigned int pic_sz = f_pic.size();
return ( pic_sz > 100 );
}
// Capture Photo and Save it to SPIFFS
void capturePhotoSaveSpiffs( void ) {
camera_fb_t * fb = NULL; // pointer
bool ok = 0; // Boolean indicating if the picture has been taken correctly
do {
// Take a photo with the camera
Serial.println("Taking a photo...");
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
return;
}
// Photo file name
Serial.printf("Picture file name: %s\n", FILE_PHOTO);
File file = SPIFFS.open(FILE_PHOTO, FILE_WRITE);
// Insert the data in the photo file
if (!file) {
Serial.println("Failed to open file in writing mode");
}
else {
file.write(fb->buf, fb->len); // payload (image), payload length
Serial.print("The picture has been saved in ");
Serial.print(FILE_PHOTO);
Serial.print(" - Size: ");
Serial.print(file.size());
Serial.println(" bytes");
}
// Close the file
file.close();
esp_camera_fb_return(fb);
// check if file has been correctly saved in SPIFFS
ok = checkPhoto(SPIFFS);
} while ( !ok );
}

Learn more about this project: ESP32-CAM Take Photo and Display in Web Server
CameraWebServer Example
You can also run the default CameraWebServer example that comes with the Arduino IDE. In your Arduino IDE, go to File > Examples > ESP32 > Camera and open the CameraWebServer example.
You can click the next link to download the .zip with the final code:
Otherwise, you need to add the TTGO T-Journal pinout to the camera_pins.h tab.

Copy the following to the camera_pins.h file.
#if defined(CAMERA_MODEL_T_JOURNAL)
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#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
Then, in the CameraWebServer tab, comment all the existing camera models, and add your camera, as follows:
// Select camera model
#define CAMERA_MODEL_T_JOURNAL
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
//#define CAMERA_MODEL_AI_THINKER
Because this camera doesn’t have PSRAM, the face recognition and detection features of this project don’t work with this camera. All the other functionalities work well.

Upload Code to the TTGO T-Journal ESP32 Camera
To upload code, you just need to connect the board to your computer, then in the Arduino IDE, go to Tools > Port and select the COM port it is connected to.
Then, you also need to select a Board model. The TTGO T-Journal is not available on the ESP32 models. So, select the following settings:
- Board: “ESP32 Wrover Module”
- Partition Scheme: “Huge APP (3MB No OTA)”

Then, simply click the Arduino IDE upload button and it is done!

Wrapping Up
This tutorial was a quick getting started guide for the TTGO T-Journal ESP32 Camera Development board. You’ve learned how to control the OLED display and how to adapt existing ESP32 camera projects to your board.
We hope you’ve found this tutorial useful.
Thank you for reading!
Comment