| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- // from: https://github.com/Z4urce/flipperzero-camera/blob/main/esp32_firmware/esp32_cam_uart_stream/esp32_cam_uart_stream.ino
- void cam_stream_setup() {
- // camera init
- 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_GRAYSCALE;
- // We don't need a big frame
- config.frame_size = FRAMESIZE_QQVGA;
- config.fb_count = 1;
- esp_err_t err = esp_camera_init(&config);
- if (err != ESP_OK) {
- Serial.printf("Camera init failed with error 0x%x", err);
- return;
- }
- // Setting high contrast to make easier to dither
- sensor_t* s = esp_camera_sensor_get();
- s->set_contrast(s, 2);
- }
- bool disable_dithering = false;
- bool invert = false;
- void cam_stream_loop() {
- bool stop_stream = false;
- // Reading serial
- if (Serial.available() > 0) {
- char r = Serial.read();
- sensor_t* s = esp_camera_sensor_get();
- switch (r) {
- case 'S':
- //stop_stream = false;
- break;
- case 's':
- /*stop_stream = true;
- preferences.putBool("streaming", false);
- preferences.end();
- ESP.restart();*/
- break;
- case 'D':
- disable_dithering = false;
- break;
- case 'd':
- disable_dithering = true;
- break;
- case 'C':
- s->set_contrast(s, s->status.contrast + 1);
- s->set_contrast(s, s->status.brightness + 1);
- break;
- case 'c':
- s->set_contrast(s, s->status.contrast - 1);
- s->set_contrast(s, s->status.brightness - 1);
- break;
- /*case 'B':
- s->set_contrast(s, s->status.brightness + 1);
- break;
- case 'b':
- s->set_contrast(s, s->status.brightness - 1);
- break;
- // Toggle cases
- case 'M': // Toggle Mirror
- s->set_hmirror(s, !s->status.hmirror);
- break;
- case '>':
- disable_dithering = !disable_dithering;
- break;
- case '<':
- invert = !invert;
- break;
- */
- // Toggle cases
- case '>': // Toggle Mirror
- s->set_hmirror(s, !s->status.hmirror);
- if (s->status.hmirror)
- s->set_vflip(s, !s->status.vflip);
- break;
- case '<':
- invert = !invert;
- if(invert)
- disable_dithering = !disable_dithering;
- break;
- default:
- break;
- }
- }
- camera_fb_t* fb = esp_camera_fb_get();
- if (!fb) {
- return;
- }
- //Length: 19200
- //Width: 160
- //Height: 120
- //Format: 2
- //Target: 128x64
- if (!disable_dithering) {
- DitherImage(fb);
- }
- uint8_t flipper_y = 0;
- for (uint8_t y = 28; y < 92; ++y) {
- Serial.print("Y:");
- Serial.print((char)flipper_y);
- size_t true_y = y * fb->width;
- for (uint8_t x = 16; x < 144; x += 8) {
- char c = 0;
- for (uint8_t j = 0; j < 8; ++j) {
- if (IsDarkBit(fb->buf[true_y + x + (7 - j)])) {
- c |= 1 << j;
- }
- }
- Serial.print(c);
- }
- ++flipper_y;
- Serial.flush();
- }
- esp_camera_fb_return(fb);
- fb = NULL;
- delay(50);
- }
- inline bool IsDarkBit(const uint8_t bit) {
- return (invert ^ (bit < 128));
- }
- void DitherImage(camera_fb_t* fb) {
- for (uint8_t y = 0; y < fb->height; ++y) {
- for (uint8_t x = 0; x < fb->width; ++x) {
- size_t current = (y * fb->width) + x;
- uint8_t oldpixel = fb->buf[current];
- uint8_t newpixel = oldpixel >= 128 ? 255 : 0;
- fb->buf[current] = newpixel;
- uint8_t quant_error = oldpixel - newpixel;
- fb->buf[(y * fb->width) + x + 1] = fb->buf[(y * fb->width) + x + 1] + quant_error * 7 / 16;
- fb->buf[(y + 1 * fb->width) + x - 1] = fb->buf[(y + 1 * fb->width) + x - 1] + quant_error * 3 / 16;
- fb->buf[(y + 1 * fb->width) + x] = fb->buf[(y + 1 * fb->width) + x] + quant_error * 5 / 16;
- fb->buf[(y + 1 * fb->width) + x + 1] = fb->buf[(y + 1 * fb->width) + x + 1] + quant_error * 1 / 16;
- }
- }
- }
|