/* caméra : https://github.com/espressif/esp32-camera * écran : https://github.com/sbcshop/Round-LCD-HAT/blob/main/lib/GC9A01A%20Datasheet.pdf * https://esp32.com/viewtopic.php?t=14376 */ // TODO refactor / cleanup #include #include "esp_camera.h" #define BOARD_ESP32CAM_AITHINKER #define CAMERA_MODEL_AI_THINKER #define RST 2 #define DC 12 #define CS 15 #define CLK 14 #define MOSI 13 #define SPI_HZ 62500000 #define MY_MODE SPI_MODE3 #define MY_BYTE MSBFIRST enum type_t { CMD = LOW, DATA = HIGH }; SPIClass *hspi = NULL; camera_fb_t *fb = NULL; camera_config_t my_cam_config; uint16_t screen[240]; uint16_t tmp[240]; void send_to_screen(SPIClass *spi, byte data, type_t type) { digitalWrite(DC, type); digitalWrite(CS, LOW); spi->beginTransaction(SPISettings(SPI_HZ, MY_BYTE, MY_MODE)); spi->transfer(data); spi->endTransaction(); digitalWrite(CS, HIGH); } void send_buffer(SPIClass *spi, uint16_t *data, int size) { digitalWrite(DC, HIGH); digitalWrite(CS, LOW); spi->beginTransaction(SPISettings(SPI_HZ, MY_BYTE, MY_MODE)); spi->transfer(data, size); spi->endTransaction(); digitalWrite(CS, HIGH); } void setup() { Serial.begin(9600); Serial.setDebugOutput(true); hspi = new SPIClass(HSPI); hspi->begin(); pinMode(hspi->pinSS(), OUTPUT); pinMode(RST, OUTPUT); pinMode(DC, OUTPUT); digitalWrite(RST, HIGH); delay(10); digitalWrite(RST, LOW); delay(10); digitalWrite(RST, HIGH); delay(20); send_to_screen(hspi, 0xEF, CMD); send_to_screen(hspi, 0xEB, CMD); send_to_screen(hspi, 0x14, DATA); send_to_screen(hspi, 0xFE, CMD); send_to_screen(hspi, 0xEF, CMD); send_to_screen(hspi, 0xEB, CMD); send_to_screen(hspi, 0x14, DATA); send_to_screen(hspi, 0x84, CMD); send_to_screen(hspi, 0x40, DATA); send_to_screen(hspi, 0x85, CMD); send_to_screen(hspi, 0xFF, DATA); send_to_screen(hspi, 0x86, CMD); send_to_screen(hspi, 0xFF, DATA); send_to_screen(hspi, 0x87, CMD); send_to_screen(hspi, 0xFF, DATA); send_to_screen(hspi, 0x88, CMD); send_to_screen(hspi, 0x0A, DATA); send_to_screen(hspi, 0x89, CMD); send_to_screen(hspi, 0x21, DATA); send_to_screen(hspi, 0x8A, CMD); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x8B, CMD); send_to_screen(hspi, 0x80, DATA); send_to_screen(hspi, 0x8C, CMD); send_to_screen(hspi, 0x01, DATA); send_to_screen(hspi, 0x8D, CMD); send_to_screen(hspi, 0x01, DATA); send_to_screen(hspi, 0x8E, CMD); send_to_screen(hspi, 0xFF, DATA); send_to_screen(hspi, 0x8F, CMD); send_to_screen(hspi, 0xFF, DATA); send_to_screen(hspi, 0xB6, CMD); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x36, CMD); send_to_screen(hspi, 0x08, DATA); //send_to_screen(hspi, 0x48, DATA); send_to_screen(hspi, 0x3A, CMD); send_to_screen(hspi, 0x05, DATA); //send_to_screen(hspi, 0x66, DATA); //send_to_screen(hspi, 0x60, DATA); send_to_screen(hspi, 0x90, CMD); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0xBD, CMD); send_to_screen(hspi, 0x06, DATA); send_to_screen(hspi, 0xBC, CMD); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0xFF, CMD); send_to_screen(hspi, 0x60, DATA); send_to_screen(hspi, 0x01, DATA); send_to_screen(hspi, 0x04, DATA); send_to_screen(hspi, 0xC3, CMD); send_to_screen(hspi, 0x13, DATA); send_to_screen(hspi, 0xC4, CMD); send_to_screen(hspi, 0x13, DATA); send_to_screen(hspi, 0xC9, CMD); send_to_screen(hspi, 0x22, DATA); send_to_screen(hspi, 0xBE, CMD); send_to_screen(hspi, 0x11, DATA); send_to_screen(hspi, 0xE1, CMD); send_to_screen(hspi, 0x10, DATA); send_to_screen(hspi, 0x0E, DATA); send_to_screen(hspi, 0xDF, CMD); send_to_screen(hspi, 0x21, DATA); send_to_screen(hspi, 0x0C, DATA); send_to_screen(hspi, 0x02, DATA); send_to_screen(hspi, 0xF0, CMD); send_to_screen(hspi, 0x45, DATA); send_to_screen(hspi, 0x09, DATA); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0x26, DATA); send_to_screen(hspi, 0x2A, DATA); send_to_screen(hspi, 0xF1, CMD); send_to_screen(hspi, 0x43, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x72, DATA); send_to_screen(hspi, 0x36, DATA); send_to_screen(hspi, 0x37, DATA); send_to_screen(hspi, 0x6F, DATA); send_to_screen(hspi, 0xF2, CMD); send_to_screen(hspi, 0x45, DATA); send_to_screen(hspi, 0x09, DATA); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0x08, DATA); send_to_screen(hspi, 0x26, DATA); send_to_screen(hspi, 0x2A, DATA); send_to_screen(hspi, 0xF3, CMD); send_to_screen(hspi, 0x43, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x72, DATA); send_to_screen(hspi, 0x36, DATA); send_to_screen(hspi, 0x37, DATA); send_to_screen(hspi, 0x6F, DATA); send_to_screen(hspi, 0xED, CMD); send_to_screen(hspi, 0x1B, DATA); send_to_screen(hspi, 0x0B, DATA); send_to_screen(hspi, 0xAE, CMD); send_to_screen(hspi, 0x77, DATA); send_to_screen(hspi, 0xCD, CMD); send_to_screen(hspi, 0x63, DATA); /* send_(hspi, 0x70,COMMAND); send_(hspi, 0x07,PARAM); send_(hspi, 0x07,PARAM); send_(hspi, 0x04,PARAM); send_(hspi, 0x0E,PARAM); send_(hspi, 0x0F,PARAM); send_(hspi, 0x09,PARAM); send_(hspi, 0x07,PARAM); send_(hspi, 0x08,PARAM); send_(hspi, 0x03,PARAM); */ send_to_screen(hspi, 0xE8, CMD); send_to_screen(hspi, 0x34, DATA); send_to_screen(hspi, 0x62, CMD); send_to_screen(hspi, 0x18, DATA); send_to_screen(hspi, 0x0D, DATA); send_to_screen(hspi, 0x71, DATA); send_to_screen(hspi, 0xED, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x18, DATA); send_to_screen(hspi, 0x0F, DATA); send_to_screen(hspi, 0x71, DATA); send_to_screen(hspi, 0xEF, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x63, CMD); send_to_screen(hspi, 0x18, DATA); send_to_screen(hspi, 0x11, DATA); send_to_screen(hspi, 0x71, DATA); send_to_screen(hspi, 0xF1, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x18, DATA); send_to_screen(hspi, 0x13, DATA); send_to_screen(hspi, 0x71, DATA); send_to_screen(hspi, 0xF3, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x70, DATA); send_to_screen(hspi, 0x64, CMD); send_to_screen(hspi, 0x28, DATA); send_to_screen(hspi, 0x29, DATA); send_to_screen(hspi, 0xF1, DATA); send_to_screen(hspi, 0x01, DATA); send_to_screen(hspi, 0xF1, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x07, DATA); send_to_screen(hspi, 0x66, CMD); send_to_screen(hspi, 0x3C, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0xCD, DATA); send_to_screen(hspi, 0x67, DATA); send_to_screen(hspi, 0x45, DATA); send_to_screen(hspi, 0x45, DATA); send_to_screen(hspi, 0x10, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x67, CMD); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x3C, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x01, DATA); send_to_screen(hspi, 0x54, DATA); send_to_screen(hspi, 0x10, DATA); send_to_screen(hspi, 0x32, DATA); send_to_screen(hspi, 0x98, DATA); send_to_screen(hspi, 0x74, CMD); send_to_screen(hspi, 0x10, DATA); send_to_screen(hspi, 0x85, DATA); send_to_screen(hspi, 0x80, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x4E, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x98, CMD); send_to_screen(hspi, 0x3E, DATA); send_to_screen(hspi, 0x07, DATA); send_to_screen(hspi, 0x35, CMD); send_to_screen(hspi, 0x21, CMD); send_to_screen(hspi, 0x11, CMD); delay(150); send_to_screen(hspi, 0x29, CMD); delay(150); send_to_screen(hspi, 0x2A, CMD); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0xEF, DATA); send_to_screen(hspi, 0x2B, CMD); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0x00, DATA); send_to_screen(hspi, 0xEF, DATA); my_cam_config.ledc_channel = LEDC_CHANNEL_0; my_cam_config.ledc_timer = LEDC_TIMER_0; my_cam_config.pin_d0 = 5; my_cam_config.pin_d1 = 18; my_cam_config.pin_d2 = 19; my_cam_config.pin_d3 = 21; my_cam_config.pin_d4 = 36; my_cam_config.pin_d5 = 39; my_cam_config.pin_d6 = 34; my_cam_config.pin_d7 = 35; my_cam_config.pin_xclk = 0; my_cam_config.pin_pclk = 22; my_cam_config.pin_vsync = 25; my_cam_config.pin_href = 23; my_cam_config.pin_sccb_sda = 26; my_cam_config.pin_sccb_scl = 27; my_cam_config.pin_pwdn = 32; //my_cam_config.xclk_freq_hz = 12000000; my_cam_config.xclk_freq_hz = 20000000; my_cam_config.pin_reset = -1; my_cam_config.pixel_format = PIXFORMAT_RGB565; my_cam_config.frame_size = FRAMESIZE_240X240; //my_cam_config.jpeg_quality = 40; my_cam_config.fb_count = 4; my_cam_config.grab_mode = CAMERA_GRAB_LATEST; esp_err_t err = esp_camera_init(&my_cam_config); if (err != ESP_OK) { Serial.printf("Camera init failed with error 0x%x", err); return; } sensor_t *my_sensor = esp_camera_sensor_get(); my_sensor->set_whitebal(my_sensor, 0); my_sensor->set_awb_gain(my_sensor, 0); my_sensor->set_exposure_ctrl(my_sensor, 0); my_sensor->set_gain_ctrl(my_sensor, 0); my_sensor->set_wpc(my_sensor, 0); my_sensor->set_raw_gma(my_sensor, 0); my_sensor->set_lenc(my_sensor, 0); my_sensor->set_dcw(my_sensor, 0); my_sensor->set_special_effect(my_sensor, 4); Serial.print("===== fin !! ====="); for(int i = 0; i < 240; i++) { screen[i] = 0x0000; } send_to_screen(hspi, 0x2C, CMD); for (int i= 0; i<240; i++) { memcpy(tmp, screen, 240 * 2); send_buffer(hspi, screen, 240 * 2); } } void loop() { fb = esp_camera_fb_get(); // TODO check si tout est bon send_to_screen(hspi, 0x2C, CMD); for (int i= 0; i<240; i++) { memcpy(tmp, (fb->buf + (i * 240 * 2)), 240 * 2); send_buffer(hspi, tmp, 240 * 2); } esp_camera_fb_return(fb); delay(5); }