Code issues

dumDumPerson
Posts: 1
Joined: Fri Jul 14, 2023 6:07 am

Code issues

Postby dumDumPerson » 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

Code: myCode.cpp Select all


/*
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);
}

Code: Original.cpp Select all

/*
* 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) {
}

Sprite
Espressif staff
Espressif staff
Posts: 10596
Joined: Thu Nov 26, 2015 4:08 am

Re: Code issues

Postby Sprite » Mon Jul 17, 2023 2:18 am

Moving Showcase -> Arduino subforum.

Who is online

Users browsing this forum: No registered users and 5 guests