Code issues
Posted: Fri Jul 14, 2023 6:46 am
Hi, I am fairly new to creating projects with esp-boards, though I have some experience with Arduinos. I wanted to gift my girlfriend a nice birthday present, a little pet robot. It's supposed to look at faces and show a blinking eye on the screen. I followed an instruction on instructables ( https://www.instructables.com/WatchEye/ ) but I used a different screen. Instead of the Adafruit LED Backpack I used an LED Matrix and a shift register. I tried around for a bit but it doesn't seem to be working.
Does this line "LedControl lc = LedControl(14, 15, 16, 1); // Pins: DIN,CLK,CS, # of Display connected" even work like that?
Any help would be greatly appreciated, I included the code below!
Best regards
dumDumPerson
Does this line "LedControl lc = LedControl(14, 15, 16, 1); // Pins: DIN,CLK,CS, # of Display connected" even work like that?
Any help would be greatly appreciated, I included the code below!
Best regards
dumDumPerson
- /*
- WatchEye - One-eyed Pet With Face Tracking
- ==========================================
- Markus opitz 2022
- www.instructables.com
- */
- // Camera
- #include "camera_index.h"
- #include "fb_gfx.h"
- #include "esp_camera.h"
- #include "fd_forward.h"
- #include "soc/rtc_cntl_reg.h" //disable brownout problems
- #include "soc/soc.h" //disable brownout problems
- // LED matrix
- #include "LedControl.h"
- LedControl lc = LedControl(14, 15, 16, 1); // Pins: DIN,CLK,CS, # of Display connected
- unsigned long delayTime = 400; // Delay between Frames
- // Put values in arrays
- byte one[] =
- {
- B00011000,
- B00111100,
- B01111110,
- B11000011,
- B11000011,
- B01111110,
- B00111100,
- B00011000
- };
- byte two[] =
- {
- B00000000,
- B00000000,
- B01111110,
- B11100111,
- B11100111,
- B01111110,
- B00000000,
- B00000000
- };
- byte three[] =
- {
- B00000000,
- B00000000,
- B00011000,
- B11111111,
- B11111111,
- B00011000,
- B00000000,
- B00000000
- };
- byte four[] =
- {
- B00000000,
- B00000000,
- B01111110,
- B11100111,
- B11100111,
- B01111110,
- B00000000,
- B00000000
- };
- // Arduino like analogWrite === SERVOS =================
- // value has to be between 0 and valueMax
- void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 180)
- {
- // calculate duty, 8191 from 2 ^ 13 - 1
- uint32_t duty = (8191 / valueMax) * min(value, valueMax);
- ledcWrite(channel, duty);
- }
- int pan_center = 90; // center the pan servo
- int tilt_center = 90; // center the tilt servo
- RTC_DATA_ATTR int pan_center_old; //remember old value in RTC
- int i;
- unsigned long runTime, newTime;
- // ===== CAMERA_MODEL_AI_THINKER =========
- #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
- bool initCamera() {
- 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;
- /*
- XGA(1024x768)
- SVGA(800x600)
- VGA(640x480)
- CIF(400x296)
- QVGA(320x240)
- HQVGA(240x176)
- QQVGA(160x120)
- */
- if (psramFound()) {
- config.frame_size = FRAMESIZE_VGA;
- config.jpeg_quality = 10;
- config.fb_count = 2;
- }
- else {
- config.frame_size = FRAMESIZE_CIF;
- config.jpeg_quality = 12;
- config.fb_count = 1;
- }
- esp_err_t result = esp_camera_init(&config);
- if (result != ESP_OK) {
- return false;
- }
- return true;
- }
- mtmn_config_t mtmn_config = { 0 };
- int detections = 0;
- int counter = 0;
- void setup() { // ================ setup =====================
- WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
- Serial.begin(115200);
- esp_sleep_enable_ext0_wakeup(GPIO_NUM_2, 1);
- // LED matrix
- lc.shutdown(0, false); // Wake up display
- lc.setIntensity(0, 5); // Set intensity level
- lc.clearDisplay(0); // Clear Displays
- // Ai-Thinker: pins 13 and 12 ===== Servos =====
- ledcSetup(2, 50, 16); //channel, freq, resolution
- ledcAttachPin(13, 2); // pin, channel
- ledcSetup(4, 50, 16);
- ledcAttachPin(12, 4);
- delay(5);
- ledcAnalogWrite(2, 110); // pan start position
- ledcAnalogWrite(4, 90); // tilt
- delay(500);
- if (!initCamera()) {
- Serial.printf("Failed to initialize camera...");
- return;
- }
- mtmn_config = mtmn_init_config();
- Serial.println("Setup complete");
- } // ================ setup end =====================
- static void draw_face_boxes(dl_matrix3du_t* image_matrix, box_array_t* boxes)
- {
- int x, y, w, h, i, half_width, half_height;
- fb_data_t fb;
- fb.width = image_matrix->w;
- fb.height = image_matrix->h;
- fb.data = image_matrix->item;
- fb.bytes_per_pixel = 3;
- fb.format = FB_BGR888;
- for (i = 0; i < boxes->len; i++) {
- // Convoluted way of finding face centre...
- x = ((int)boxes->box[i].box_p[0]);
- w = (int)boxes->box[i].box_p[2] - x + 1;
- half_width = w / 2;
- int face_center_pan = x + half_width; // image frame face centre x co-ordinate
- y = (int)boxes->box[i].box_p[1];
- h = (int)boxes->box[i].box_p[3] - y + 1;
- half_height = h / 2;
- int face_center_tilt = y + half_height; // image frame face centre y co-ordinate
- // assume QVGA 320x240 CIF(400x296) VGA(640x480) SVGA(800x600)
- // int sensor_width = 320; 400 640 800
- // int sensor_height = 240; 296 480 600
- // int lens_fov = 45 45 45 45
- // float diagonal = sqrt(sq(sensor_width) + sq(sensor_height)); // pixels along the diagonal
- // float pixels_per_degree = diagonal / lens_fov;
- // 400/45 = 8.89 498/45 = 11.05 800/45 = 17.78 1000/45 = 22.22
- // QVGA 320x240
- // float move_to_x = pan_center - ((-160 + face_center_pan) / 8.89 -5) ; // -5 correct that the lens is not centered
- // float move_to_y = tilt_center + ((-120 + face_center_tilt) / 8.89) ;
- // CIF(400x296)
- // float move_to_x = pan_center - ((-200 + face_center_pan) / 11.05 -5) ;
- // float move_to_y = tilt_center + ((-148 + face_center_tilt) / 11.05) ;
- // VGA(640x480)
- float move_to_x = pan_center - ((-320 + face_center_pan) / 17.78 - 5);
- float move_to_y = tilt_center + ((-240 + face_center_tilt) / 17.78);
- // SVGA(800x600)
- // float move_to_x = pan_center - ((-400 + face_center_pan) / 22.22 -5) ;
- // float move_to_y = tilt_center + ((-300 + face_center_tilt) / 22.22) ;
- Serial.print("box is drawn ");
- pan_center = (pan_center + move_to_x) / 2;
- //pan_center = 180 - pan_center;
- if ((pan_center_old - pan_center < 10) && (pan_center_old - pan_center > -10)) {
- sone();
- delay(300);
- stwo();
- delay(300);
- sthree();
- delay(300);
- sfour();
- delay(300);
- }
- pan_center_old = pan_center; // save servo position
- Serial.print(pan_center); Serial.print(" x "); Serial.print(move_to_x); Serial.print(" ");
- ledcAnalogWrite(2, pan_center); // channel, 0-180
- delay(2);
- tilt_center = (tilt_center + move_to_y) / 2;
- int reversed_tilt_center = map(tilt_center, 60, 130, 130, 60);
- reversed_tilt_center = 180 - reversed_tilt_center;
- Serial.print(reversed_tilt_center); Serial.print(" y "); Serial.print(move_to_y);
- Serial.println("");
- ledcAnalogWrite(4, reversed_tilt_center); // channel, 50-140
- delay(2);
- }
- }
- void sone()
- {
- for (int i = 0; i < 8; i++)
- {
- lc.setRow(0, i, one[i]);
- }
- }
- void stwo()
- {
- for (int i = 0; i < 8; i++)
- {
- lc.setRow(0, i, two[i]);
- }
- }
- void sthree()
- {
- for (int i = 0; i < 8; i++)
- {
- lc.setRow(1, i, three[i]);
- }
- }
- void sfour()
- {
- for (int i = 0; i < 8; i++)
- {
- lc.setRow(1, i, four[i]);
- }
- }
- void loop() {
- // camera and servos ==========================
- camera_fb_t* frame;
- frame = esp_camera_fb_get();
- dl_matrix3du_t* image_matrix = dl_matrix3du_alloc(1, frame->width, frame->height, 3);
- fmt2rgb888(frame->buf, frame->len, frame->format, image_matrix->item);
- esp_camera_fb_return(frame);
- box_array_t* boxes = face_detect(image_matrix, &mtmn_config);
- // if there is no face, look for it
- if (boxes != NULL) {
- Serial.printf("Faces detected");
- draw_face_boxes(image_matrix, boxes); // draw boxes and move servos
- runTime = millis();
- }
- newTime = millis();
- if (newTime - runTime > 15000) { // no action for more than 15 sec --> sleep; 15000 = 15sec
- ledcAnalogWrite(2, 110); // pan, channel, 0-180
- ledcAnalogWrite(4, 110); // tilt
- delay(200);
- stwo();
- delay(200);
- sthree();
- esp_deep_sleep_start();
- }
- dl_matrix3du_free(image_matrix);
- delay(1);
- }
- /*
- * WatchEye - One-eyed Pet With Face Tracking
- * ==========================================
- * Markus opitz 2022
- * www.instructables.com
- */
- // Camera
- #include "camera_index.h"
- #include "fb_gfx.h"
- #include "esp_camera.h"
- #include "fd_forward.h"
- #include "soc/rtc_cntl_reg.h" //disable brownout problems
- #include "soc/soc.h" //disable brownout problems
- // LED matrix
- #include <Wire.h>
- #include "Adafruit_LEDBackpack.h"
- #include "Adafruit_GFX.h"
- #include "blink.h"
- Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
- uint8_t
- blinkIndex[] = {
- 1, 2, 3, 4, 3, 2, 1 },
- // Blink bitmap sequence
- blinkCountdown = 100, // 100 Countdown to next blink (in frames)
- gazeCountdown = 75, // 75 Countdown to next eye movement
- gazeFrames = 50; // 50 Duration of eye movement (smaller = faster)
- int8_t
- eyeX = 3, eyeY = 3, // Current eye position
- newX = 3, newY = 3, // Next eye position
- dX = 0, dY = 0; // Distance from prior to new position
- // Arduino like analogWrite === SERVOS =================
- // value has to be between 0 and valueMax
- void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 180)
- {
- // calculate duty, 8191 from 2 ^ 13 - 1
- uint32_t duty = (8191 / valueMax) * min(value, valueMax);
- ledcWrite(channel, duty);
- }
- int pan_center = 90; // center the pan servo
- int tilt_center = 90; // center the tilt servo
- RTC_DATA_ATTR int pan_center_old; //remember old value in RTC
- int i;
- unsigned long runTime, newTime;
- // ===== CAMERA_MODEL_AI_THINKER =========
- #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
- bool initCamera() {
- 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;
- /*
- XGA(1024x768)
- SVGA(800x600)
- VGA(640x480)
- CIF(400x296)
- QVGA(320x240)
- HQVGA(240x176)
- QQVGA(160x120)
- */
- if (psramFound()) {
- config.frame_size = FRAMESIZE_VGA;
- config.jpeg_quality = 10;
- config.fb_count = 2;
- } else {
- config.frame_size = FRAMESIZE_CIF;
- config.jpeg_quality = 12;
- config.fb_count = 1;
- }
- esp_err_t result = esp_camera_init(&config);
- if (result != ESP_OK) {
- return false;
- }
- return true;
- }
- mtmn_config_t mtmn_config = {0};
- int detections = 0;
- int counter = 0;
- void setup() { // ================ setup =====================
- WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
- Serial.begin(115200);
- esp_sleep_enable_ext0_wakeup(GPIO_NUM_2, 1);
- // LED matrix
- Wire.begin(14, 15);//SDA, SCL = GPIO14, GPIO15
- matrix.begin(0x70);
- matrix.setRotation(3);
- matrix.setBrightness(4);
- matrix.setTextColor(LED_ON);
- matrix.clear();
- matrix.writeDisplay();
- blinkblink();
- // Ai-Thinker: pins 13 and 12 ===== Servos =====
- ledcSetup(2, 50, 16); //channel, freq, resolution
- ledcAttachPin(13, 2); // pin, channel
- ledcSetup(4, 50, 16);
- ledcAttachPin(12, 4);
- delay(5);
- ledcAnalogWrite(2, 110); // pan start position
- ledcAnalogWrite(4, 90); // tilt
- delay(500);
- if (!initCamera()) {
- Serial.printf("Failed to initialize camera...");
- return;
- }
- mtmn_config = mtmn_init_config();
- Serial.println("Setup complete");
- } // ================ setup end =====================
- static void draw_face_boxes(dl_matrix3du_t *image_matrix, box_array_t *boxes)
- {
- int x, y, w, h, i, half_width, half_height;
- fb_data_t fb;
- fb.width = image_matrix->w;
- fb.height = image_matrix->h;
- fb.data = image_matrix->item;
- fb.bytes_per_pixel = 3;
- fb.format = FB_BGR888;
- for (i = 0; i < boxes->len; i++) {
- // Convoluted way of finding face centre...
- x = ((int)boxes->box[i].box_p[0]);
- w = (int)boxes->box[i].box_p[2] - x + 1;
- half_width = w / 2;
- int face_center_pan = x + half_width; // image frame face centre x co-ordinate
- y = (int)boxes->box[i].box_p[1];
- h = (int)boxes->box[i].box_p[3] - y + 1;
- half_height = h / 2;
- int face_center_tilt = y + half_height; // image frame face centre y co-ordinate
- // assume QVGA 320x240 CIF(400x296) VGA(640x480) SVGA(800x600)
- // int sensor_width = 320; 400 640 800
- // int sensor_height = 240; 296 480 600
- // int lens_fov = 45 45 45 45
- // float diagonal = sqrt(sq(sensor_width) + sq(sensor_height)); // pixels along the diagonal
- // float pixels_per_degree = diagonal / lens_fov;
- // 400/45 = 8.89 498/45 = 11.05 800/45 = 17.78 1000/45 = 22.22
- // QVGA 320x240
- // float move_to_x = pan_center - ((-160 + face_center_pan) / 8.89 -5) ; // -5 correct that the lens is not centered
- // float move_to_y = tilt_center + ((-120 + face_center_tilt) / 8.89) ;
- // CIF(400x296)
- // float move_to_x = pan_center - ((-200 + face_center_pan) / 11.05 -5) ;
- // float move_to_y = tilt_center + ((-148 + face_center_tilt) / 11.05) ;
- // VGA(640x480)
- float move_to_x = pan_center - ((-320 + face_center_pan) / 17.78 -5) ;
- float move_to_y = tilt_center + ((-240 + face_center_tilt) / 17.78) ;
- // SVGA(800x600)
- // float move_to_x = pan_center - ((-400 + face_center_pan) / 22.22 -5) ;
- // float move_to_y = tilt_center + ((-300 + face_center_tilt) / 22.22) ;
- Serial.print("box is drawn ");
- pan_center = (pan_center + move_to_x) / 2 ;
- //pan_center = 180 - pan_center;
- if ((pan_center_old - pan_center < 10) && (pan_center_old - pan_center > -10)){
- blinkblink();
- }
- pan_center_old = pan_center; // save servo position
- Serial.print(pan_center); Serial.print(" x "); Serial.print(move_to_x);Serial.print(" ");
- ledcAnalogWrite(2, pan_center); // channel, 0-180
- delay(2);
- tilt_center = (tilt_center + move_to_y) / 2;
- int reversed_tilt_center = map(tilt_center, 60, 130, 130, 60);
- reversed_tilt_center = 180 - reversed_tilt_center;
- Serial.print(reversed_tilt_center); Serial.print(" y "); Serial.print(move_to_y);
- Serial.println("");
- ledcAnalogWrite(4, reversed_tilt_center); // channel, 50-140
- delay(2);
- }
- }
- void loop() {
- // camera and servos ==========================
- camera_fb_t * frame;
- frame = esp_camera_fb_get();
- dl_matrix3du_t *image_matrix = dl_matrix3du_alloc(1, frame->width, frame->height, 3);
- fmt2rgb888(frame->buf, frame->len, frame->format, image_matrix->item);
- esp_camera_fb_return(frame);
- box_array_t *boxes = face_detect(image_matrix, &mtmn_config);
- // if there is no face, look for it
- while (boxes == NULL) {
- Serial.printf("look for faces");
- // add a searching modus here
- // searching();
- }
- if (boxes != NULL) {
- Serial.printf("Faces detected");
- draw_face_boxes(image_matrix, boxes); // draw boxes and move servos
- runTime = millis();
- }
- newTime = millis();
- if (newTime-runTime > 15000) { // no action for more than 15 sec --> sleep; 15000 = 15sec
- ledcAnalogWrite(2, 110); // pan, channel, 0-180
- ledcAnalogWrite(4, 110); // tilt
- matrix.clear();
- matrix.writeDisplay();
- delay(100);
- esp_deep_sleep_start();
- }
- dl_matrix3du_free(image_matrix);
- // camera and servos === END ========================
- delay(1);
- }
- void blinkblink()
- {
- // eye + blink =======================
- for (int i = 0; i < 28; i++) {
- matrix.clear();
- matrix.drawBitmap(0, 0,
- blinkImg[
- (blinkCountdown < sizeof(blinkIndex)) ? // Currently blinking?
- blinkIndex[blinkCountdown] : // Yes, look up bitmap #
- 0 // No, show bitmap 0
- ], 8, 8, LED_ON);
- // Decrement blink counter. At end, set random time for next blink.
- if(--blinkCountdown == 0) blinkCountdown = random(5, 180);
- // Add a pupil (2x2 black square) atop the blinky eyeball bitmap.
- // Periodically, the pupil moves to a new position...
- if(--gazeCountdown <= gazeFrames) {
- // Eyes are in motion - draw pupil at interim position
- matrix.fillRect(
- newX - (dX * gazeCountdown / gazeFrames),
- newY - (dY * gazeCountdown / gazeFrames),
- 2, 2, LED_OFF);
- if(gazeCountdown == 0) { // Last frame?
- eyeX = newX;
- eyeY = newY; // Yes. What's new is old, then...
- do { // Pick random positions until one is within the eye circle
- newX = random(7);
- newY = random(7);
- dX = newX - 3;
- dY = newY - 3;
- }
- while((dX * dX + dY * dY) >= 10); // Thank you Pythagoras
- dX = newX - eyeX; // Horizontal distance to move
- dY = newY - eyeY; // Vertical distance to move
- gazeFrames = random(5, 20); // Duration of eye movement
- gazeCountdown = random(gazeFrames, 120); // Count to end of next movement
- }
- }
- else {
- // Not in motion yet -- draw pupil at current static position
- matrix.fillRect(eyeX, eyeY, 2, 2, LED_OFF);
- }
- delay(5);
- matrix.writeDisplay();
- }
- }
- void searching(void) {
- }