esp32_cam_uart_stream.ino 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "esp_camera.h"
  2. #define PWDN_GPIO_NUM 32
  3. #define RESET_GPIO_NUM -1
  4. #define XCLK_GPIO_NUM 0
  5. #define SIOD_GPIO_NUM 26
  6. #define SIOC_GPIO_NUM 27
  7. #define Y9_GPIO_NUM 35
  8. #define Y8_GPIO_NUM 34
  9. #define Y7_GPIO_NUM 39
  10. #define Y6_GPIO_NUM 36
  11. #define Y5_GPIO_NUM 21
  12. #define Y4_GPIO_NUM 19
  13. #define Y3_GPIO_NUM 18
  14. #define Y2_GPIO_NUM 5
  15. #define VSYNC_GPIO_NUM 25
  16. #define HREF_GPIO_NUM 23
  17. #define PCLK_GPIO_NUM 22
  18. void setup() {
  19. Serial.begin(230400);
  20. camera_config_t config;
  21. config.ledc_channel = LEDC_CHANNEL_0;
  22. config.ledc_timer = LEDC_TIMER_0;
  23. config.pin_d0 = Y2_GPIO_NUM;
  24. config.pin_d1 = Y3_GPIO_NUM;
  25. config.pin_d2 = Y4_GPIO_NUM;
  26. config.pin_d3 = Y5_GPIO_NUM;
  27. config.pin_d4 = Y6_GPIO_NUM;
  28. config.pin_d5 = Y7_GPIO_NUM;
  29. config.pin_d6 = Y8_GPIO_NUM;
  30. config.pin_d7 = Y9_GPIO_NUM;
  31. config.pin_xclk = XCLK_GPIO_NUM;
  32. config.pin_pclk = PCLK_GPIO_NUM;
  33. config.pin_vsync = VSYNC_GPIO_NUM;
  34. config.pin_href = HREF_GPIO_NUM;
  35. config.pin_sscb_sda = SIOD_GPIO_NUM;
  36. config.pin_sscb_scl = SIOC_GPIO_NUM;
  37. config.pin_pwdn = PWDN_GPIO_NUM;
  38. config.pin_reset = RESET_GPIO_NUM;
  39. config.xclk_freq_hz = 20000000;
  40. config.pixel_format = PIXFORMAT_GRAYSCALE;
  41. // We don't need a big frame
  42. config.frame_size = FRAMESIZE_QQVGA;
  43. config.fb_count = 1;
  44. // camera init
  45. esp_err_t err = esp_camera_init(&config);
  46. if (err != ESP_OK) {
  47. Serial.printf("Camera init failed with error 0x%x", err);
  48. return;
  49. }
  50. // Setting high contrast to make easier to dither
  51. sensor_t * s = esp_camera_sensor_get();
  52. s->set_contrast(s, 2);
  53. }
  54. bool stop_stream = false;
  55. bool disable_dithering = false;
  56. bool invert = false;
  57. void loop() {
  58. // Reading serial
  59. if (Serial.available() > 0) {
  60. char r = Serial.read();
  61. sensor_t * s = esp_camera_sensor_get();
  62. switch(r) {
  63. case 'S':
  64. stop_stream = false;
  65. break;
  66. case 's':
  67. stop_stream = true;
  68. break;
  69. case 'D':
  70. disable_dithering = false;
  71. break;
  72. case 'd':
  73. disable_dithering = true;
  74. break;
  75. case 'C':
  76. s->set_contrast(s, s->status.contrast + 1);
  77. break;
  78. case 'c':
  79. s->set_contrast(s, s->status.contrast - 1);
  80. break;
  81. case 'B':
  82. s->set_contrast(s, s->status.brightness + 1);
  83. break;
  84. case 'b':
  85. s->set_contrast(s, s->status.brightness - 1);
  86. break;
  87. // Toggle cases
  88. case 'M': // Toggle Mirror
  89. s->set_hmirror(s, !s->status.hmirror);
  90. break;
  91. case '>':
  92. disable_dithering = !disable_dithering;
  93. break;
  94. case '<':
  95. invert = !invert;
  96. default:
  97. break;
  98. }
  99. }
  100. if (stop_stream){
  101. return;
  102. }
  103. camera_fb_t* fb = esp_camera_fb_get();
  104. if (!fb) {
  105. return;
  106. }
  107. //Length: 19200
  108. //Width: 160
  109. //Height: 120
  110. //Format: 2
  111. //Target: 128x64
  112. if (!disable_dithering) {
  113. DitherImage(fb);
  114. }
  115. uint8_t flipper_y = 0;
  116. for(uint8_t y = 28; y < 92; ++y) {
  117. Serial.print("Y:");
  118. Serial.print((char)flipper_y);
  119. size_t true_y = y * fb->width;
  120. for (uint8_t x = 16; x < 144; x+=8){
  121. char c = 0;
  122. for(uint8_t j = 0; j < 8; ++j){
  123. if (IsDarkBit(fb->buf[true_y + x + (7-j)])){
  124. c |= 1 << j;
  125. }
  126. }
  127. Serial.print(c);
  128. }
  129. ++flipper_y;
  130. Serial.flush();
  131. }
  132. esp_camera_fb_return(fb);
  133. fb = NULL;
  134. delay(50);
  135. }
  136. bool IsDarkBit(uint8_t bit){
  137. bool result = bit < 128;
  138. if (invert){
  139. result = !result;
  140. }
  141. return result;
  142. }
  143. void DitherImage(camera_fb_t* fb) {
  144. for(uint8_t y = 0; y < fb->height; ++y){
  145. for (uint8_t x = 0; x < fb->width; ++x){
  146. size_t current = (y*fb->width) + x;
  147. uint8_t oldpixel = fb->buf[current];
  148. uint8_t newpixel = oldpixel >= 128 ? 255 : 0;
  149. fb->buf[current] = newpixel;
  150. uint8_t quant_error = oldpixel - newpixel;
  151. fb->buf[(y*fb->width) + x + 1] = fb->buf[(y*fb->width) + x + 1] + quant_error * 7 / 16;
  152. fb->buf[(y+1*fb->width) + x-1] = fb->buf[(y+1*fb->width) + x-1] + quant_error * 3 / 16;
  153. fb->buf[(y + 1*fb->width) + x] = fb->buf[(y + 1*fb->width) + x] + quant_error * 5 / 16;
  154. fb->buf[(y+1*fb->width) + x+1] = fb->buf[(y+1*fb->width) + x+1] + quant_error * 1 / 16;
  155. }
  156. }
  157. }