繼續前一篇初次設定 ESP32CAM的實作,想將ESP32CAM做一個簡單的相機功能,或是加上人體感應器(PIR),當感應物體移動時,就拍照存到SD卡,或是寄出照片到 Gmail 信箱等,都是想實作完成的項目。接下來就看一下如何將拍照的影像呈現到顯示器,我用的型號是 ST7789 的1.5吋 TFT-LCD,解析度是 240x240,影像品質還可以,足可呈現拍攝的影像。
上傳程式到 ESP32時,需將IO0接地(如下圖連接的橘色線條)。上傳完成後,要獨立執行上傳到ESP32CAM時,需將IO0與接地的線分開(如下圖連接的橘色線條)。
[材料]
- USB轉TTL序列傳輸線 CP2102
- ESP32CAM開發板
- ST7789 1.5" TFT-LCD
- 排線 x n 條
[接線圖]
| ESP32CAM | CP2012 | ST7789 1.5" TFT-LCD |
|---|---|---|
| 5V | 5V(VCC) | VCC |
| GND | GND | GND |
| VOR | TX | - |
| VOT | RX | - |
| IO0 | GND | - |
| GPIO2 | - | RES(RST) |
| GPIO14 | - | MOSI(SDA) |
| GPIO15 | - | SCLK(SCK) |
| GPIO13 | - | DC |
[安裝程式庫]
本實作需要安裝以下程式庫: 程式庫(Library)安裝方法請參考另一篇文章: Arduino筆記:安裝 Arduino IDE 程式庫(Library)。[程式]
參考的程式是 liefyuan 在 Github 的程式庫:Arduino_ST7789_Comp。接好 ST7789 及 ESP32CAM 的線路,將程式上傳。只要執行就會開啟 LED 閃光燈,這個 LED 燈太刺眼了,想辦法將它關掉。找了一些文件,發現這個閃光燈是接在 GPIO4,而原來的程式 TFT_DC 就是接到 GPIO4。為了解決不要開閃光燈問題,我將 ST7789 連接DC的線改接到 ESP32CAM 的 GPIO13,並加上一段關閉閃光燈的程式碼如下:
pinMode(4, OUTPUT); //GPIO4 是 LED閃光燈的IO digitalWrite(4, LOW); //關閉閃光燈修改後的程式如下:
#include <Adafruit_GFX.h> // Core graphics library
#include <Arduino_ST7789_Comp.h> // Hardware-specific library for ST7789
#include <esp_camera.h>
#include <SPI.h> // Arduino SPI library
// ST7789 TFT 模組接線設定
#define TFT_RST 2 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC 13
#define TFT_MOSI 14 // Data out
#define TFT_SCLK 15 // Clock out
// Initialize Adafruit ST7789 TFT library
Arduino_ST7789 tft = Arduino_ST7789(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK);
#define SCREEN_WIDTH 240
#define SCREEN_HEIGHT 240
#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
static camera_config_t camera_config = {
.pin_pwdn = PWDN_GPIO_NUM,
.pin_reset = RESET_GPIO_NUM,
.pin_xclk = XCLK_GPIO_NUM,
.pin_sscb_sda = SIOD_GPIO_NUM,
.pin_sscb_scl = SIOC_GPIO_NUM,
.pin_d7 = Y9_GPIO_NUM,
.pin_d6 = Y8_GPIO_NUM,
.pin_d5 = Y7_GPIO_NUM,
.pin_d4 = Y6_GPIO_NUM,
.pin_d3 = Y5_GPIO_NUM,
.pin_d2 = Y4_GPIO_NUM,
.pin_d1 = Y3_GPIO_NUM,
.pin_d0 = Y2_GPIO_NUM,
.pin_vsync = VSYNC_GPIO_NUM,
.pin_href = HREF_GPIO_NUM,
.pin_pclk = PCLK_GPIO_NUM,
.xclk_freq_hz = 20000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_RGB565,
.frame_size = FRAMESIZE_HQVGA,
.jpeg_quality = 12,
.fb_count = 1,
};
byte x,y;
uint8_t oldpixel, newpixel;
int quanterror;
esp_err_t camera_init(){
//initialize the camera
esp_err_t err = esp_camera_init(&camera_config);
if (err != ESP_OK) {
Serial.print("Camera Init Failed");
return err;
}
sensor_t * s = esp_camera_sensor_get();
//初始化影像拍攝翻轉及色彩飽和度
if (s->id.PID == OV2640_PID) {
s->set_vflip(s, 1);//flip it back
s->set_brightness(s, 1);//up the blightness just a bit
s->set_contrast(s, 1);
}
Serial.print("Camera Init OK");
return ESP_OK;
}
void showImage(void)
{
camera_fb_t *fb = esp_camera_fb_get();
// 顯示影像
tft.drawEsp32camImage(0, 0, 240, 480, (uint8_t*)fb->buf);
esp_camera_fb_return(fb);
}
void setup(void) {
Serial.begin(115200);
// 關閉 ESP32-CAM 板上的 LED閃光燈
pinMode(4, OUTPUT); //GPIO4 是 LED閃光燈的IO
digitalWrite(4, LOW); //關閉閃光燈
// 假使顯示器有 CS pin 試著使用 SPI_MODE0
tft.init(240, 240); // Init ST7789 display 240x240 pixel
// 將影像轉90度,如果影像翻轉,可將這行改成註解或刪除
tft.setRotation(2);
Serial.println(F("Initialized"));
uint16_t time = millis();
tft.fillScreen( WHITE);
time = millis() - time;
camera_init();
Serial.println("done");
delay(1000);
}
void loop() {
showImage();
}

張貼留言